Passed
Push — version-4 ( 84aff8...d98195 )
by Sebastian
02:28
created

MapFeaturesTrait::associateWith()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 7
cts 7
cp 1
crap 2
rs 10
1
<?php
2
declare(strict_types=1);
3
/*
4
 * Copyright (C) 2022 Sebastian Böttger <[email protected]>
5
 * You may use, distribute and modify this code under the
6
 * terms of the MIT license.
7
 *
8
 * You should have received a copy of the MIT license with
9
 * this file. If not, please visit: https://opensource.org/licenses/mit-license.php
10
 */
11
12
namespace Seboettg\Collection\Lists\MapFeatures;
13
14
use Seboettg\Collection\Lists\ListInterface;
15
use Seboettg\Collection\Map\MapInterface;
16
use Seboettg\Collection\Map\Pair;
17
use function Seboettg\Collection\Assert\assertScalar;
18
use function Seboettg\Collection\Assert\assertType;
19
use function Seboettg\Collection\Lists\emptyList;
20
use function Seboettg\Collection\Map\emptyMap;
21
22
/**
23
 * @property array $array Base array of this data structure
24
 */
25
trait MapFeaturesTrait
26
{
27
    /**
28
     * @inheritDoc
29
     */
30
    public function groupBy(callable $keySelector): MapInterface
31
    {
32
        $map = emptyMap();
33
        foreach ($this->array as $value) {
34
            $key = $keySelector($value);
35
            if (!$map->contains($key) || !$map[$key] instanceof ListInterface) {
36
                $map->put($key, emptyList());
37
            }
38
            $map->get($key)->add($value);
39
        }
40
        return $map;
41
    }
42
43
    /**
44
     * @inheritDoc
45
     * @param callable $transform f(item: mixed) -> Pair<scalar, mixed>
46
     * @return MapInterface
47
     */
48
    public function associate(callable $transform): MapInterface
49
    {
50
        $map = emptyMap();
51
        foreach ($this->array as $item) {
52
            $pair = $transform($item);
53
            assertType($pair, Pair::class, sprintf(
54
                "The return value of the callable must be of type %s",
55
                Pair::class
56
            ));
57
            assertScalar($pair->getKey(), "The key of the returned Pair of the callable must be a scalar.");
58
            $map[$pair->getKey()] = $pair->getValue();
59
        }
60
        return $map;
61
    }
62
63
    /**
64
     * @inheritDoc
65
     * @param callable $keySelector f(value: mixed) -> scalar
66
     * @return MapInterface
67
     */
68 1
    public function associateBy(callable $keySelector): MapInterface
69
    {
70 1
        $map = emptyMap();
71 1
        foreach ($this->array as $item) {
72 1
            $key = $keySelector($item);
73 1
            assertScalar($key, "The return value of the callable must be a scalar.");
74 1
            $map[$key] = $item;
75
        }
76 1
        return $map;
77
    }
78
79
    /**
80
     * @inheritDoc
81
     * @param callable $valueSelector
82
     * @return MapInterface
83
     */
84 1
    public function associateWith(callable $valueSelector): MapInterface
85
    {
86 1
        $map = emptyMap();
87 1
        foreach ($this->array as $item) {
88 1
            assertScalar($item,
89 1
                "All entries of the list must be scalar values in order to use \"associateWith\".");
90 1
            $map[$item] = $valueSelector($item);
91
        }
92 1
        return $map;
93
    }
94
95 1
    public function toMap(): MapInterface
96
    {
97 1
        $result = emptyMap();
98 1
        foreach ($this->array as $pair) {
99 1
            assertType(
100 1
                $pair,
101 1
                Pair::class,
102 1
                sprintf("Each item of this list must be of type %s.", Pair::class)
103
            );
104 1
            $result[$pair->getKey()] = $pair->getValue();
105
        }
106 1
        return $result;
107
    }
108
}
109