MapFeaturesTrait::groupBy()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 11
ccs 8
cts 8
cp 1
crap 4
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\Lists\listOf;
21
use function Seboettg\Collection\Map\emptyMap;
22
use function Seboettg\Collection\Map\mapOf;
23
use function Seboettg\Collection\Map\pair;
24
25
/**
26
 * @property array $array Base array of this data structure
27
 */
28
trait MapFeaturesTrait
29
{
30
31
    /**
32
     * @inheritDoc
33
     * @param callable $predicate - f(item: mixed) -> bool
34
     * @return MapInterface<string, ListInterface>
35
     */
36 1
    public function partition(callable $predicate): MapInterface
37
    {
38 1
        $first = listOf(...array_filter($this->array, $predicate));
39 1
        return mapOf(
40 1
            pair("first", $first),
41 1
            pair("second", $this->minus($first))
0 ignored issues
show
Bug introduced by
It seems like minus() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

41
            pair("second", $this->/** @scrutinizer ignore-call */ minus($first))
Loading history...
42
        );
43
    }
44
45
    /**
46
     * @inheritDoc
47
     */
48 1
    public function groupBy(callable $keySelector): MapInterface
49
    {
50 1
        $map = emptyMap();
51 1
        foreach ($this->array as $value) {
52 1
            $key = $keySelector($value);
53 1
            if (!$map->contains($key) || !$map[$key] instanceof ListInterface) {
54 1
                $map->put($key, emptyList());
55
            }
56 1
            $map->get($key)->add($value);
57
        }
58 1
        return $map;
59
    }
60
61
    /**
62
     * @inheritDoc
63
     * @param callable $transform f(item: mixed) -> Pair<scalar, mixed>
64
     * @return MapInterface
65
     */
66 3
    public function associate(callable $transform): MapInterface
67
    {
68 3
        $map = emptyMap();
69 3
        foreach ($this->array as $item) {
70 3
            $pair = $transform($item);
71 2
            assertType($pair, Pair::class, sprintf(
72 2
                "The return value of the callable must be of type %s",
73 2
                Pair::class
74
            ));
75 1
            assertScalar($pair->getKey(), "The key of the returned Pair of the callable must be a scalar.");
76 1
            $map[$pair->getKey()] = $pair->getValue();
77
        }
78 1
        return $map;
79
    }
80
81
    /**
82
     * @inheritDoc
83
     * @param callable $keySelector f(value: mixed) -> scalar
84
     * @return MapInterface
85
     */
86 1
    public function associateBy(callable $keySelector): MapInterface
87
    {
88 1
        $map = emptyMap();
89 1
        foreach ($this->array as $item) {
90 1
            $key = $keySelector($item);
91 1
            assertScalar($key, "The return value of the callable must be a scalar.");
92 1
            $map[$key] = $item;
93
        }
94 1
        return $map;
95
    }
96
97
    /**
98
     * @inheritDoc
99
     * @param callable $valueSelector
100
     * @return MapInterface
101
     */
102 1
    public function associateWith(callable $valueSelector): MapInterface
103
    {
104 1
        $map = emptyMap();
105 1
        foreach ($this->array as $item) {
106 1
            assertScalar($item,
107 1
                "All entries of the list must be scalar values in order to use \"associateWith\".");
108 1
            $map[$item] = $valueSelector($item);
109
        }
110 1
        return $map;
111
    }
112
113
    /**
114
     * @inheritDoc
115
     */
116 2
    public function toMap(): MapInterface
117
    {
118 2
        $result = emptyMap();
119 2
        foreach ($this->array as $pair) {
120 2
            assertType(
121 2
                $pair,
122 2
                Pair::class,
123 2
                sprintf("Each item of this list must be of type %s.", Pair::class)
124
            );
125 2
            $result[$pair->getKey()] = $pair->getValue();
126
        }
127 2
        return $result;
128
    }
129
}
130