Map::groupBy()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Compose\Lazy;
5
6
use Innmind\Compose\Lazy;
7
use Innmind\Immutable\{
8
    MapInterface,
9
    Map as Base,
10
    Str,
11
    Sequence,
12
    Pair,
13
    SetInterface,
14
    StreamInterface,
15
    Exception\LogicException
16
};
17
18
final class Map implements MapInterface
19
{
20
    private $keyType;
21
    private $valueType;
22
    private $values;
23
    private $loaded;
24
25 28
    public function __construct(string $keyType, string $valueType)
26
    {
27 28
        $this->keyType = new Str($keyType);
28 28
        $this->valueType = new Str($valueType);
29 28
        $this->values = new Base('mixed', 'mixed');
30 28
    }
31
32 28
    public static function of(string $keyType, string $valueType, Pair ...$values): self
33
    {
34 28
        $self = new self($keyType, $valueType);
35 28
        $self->values = Sequence::of(...$values)->reduce(
36 28
            $self->values,
37 28
            static function(Base $map, Pair $pair): Base {
38 28
                return $map->put(
39 28
                    $pair->key(),
40 28
                    $pair->value()
41
                );
42 28
            }
43
        );
44
45 28
        return $self;
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51 12
    public function keyType(): Str
52
    {
53 12
        return $this->keyType;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 12
    public function valueType(): Str
60
    {
61 12
        return $this->valueType;
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 6
    public function size(): int
68
    {
69 6
        return $this->loadedMap()->size();
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 5
    public function count(): int
76
    {
77 5
        return $this->size();
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 1
    public function current()
84
    {
85 1
        return $this->load($this->values->current());
86
    }
87
88
    /**
89
     * {@inheritdoc}
90
     */
91 1
    public function key()
92
    {
93 1
        return $this->load($this->values->key());
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 1
    public function next()
100
    {
101 1
        $this->values->next();
102 1
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 1
    public function rewind()
108
    {
109 1
        $this->values->rewind();
110 1
    }
111
112
    /**
113
     * {@inheritdoc}
114
     */
115 1
    public function valid()
116
    {
117 1
        return $this->values->valid();
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 1
    public function offsetExists($offset): bool
124
    {
125 1
        return $this->contains($offset);
126
    }
127
128
    /**
129
     * {@inheritdoc}
130
     */
131 1
    public function offsetGet($offset)
132
    {
133 1
        return $this->get($offset);
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 1
    public function offsetSet($offset, $value)
140
    {
141 1
        throw new LogicException('You can\'t modify a map');
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147 1
    public function offsetUnset($offset)
148
    {
149 1
        throw new LogicException('You can\'t modify a map');
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155 3
    public function put($key, $value): MapInterface
156
    {
157 3
        return $this->loadedMap()->put($key, $value);
158
    }
159
160
    /**
161
     * {@inheritdoc}
162
     */
163 16
    public function get($key)
164
    {
165 16
        return $this->loadedMap()->get($key);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 3
    public function contains($key): bool
172
    {
173 3
        return $this->loadedMap()->contains($key);
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179 24
    public function clear(): MapInterface
180
    {
181 24
        return new Base((string) $this->keyType, (string) $this->valueType);
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187 1
    public function equals(MapInterface $map): bool
188
    {
189 1
        return $this->loadedMap()->equals($map);
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195 1
    public function filter(callable $predicate): MapInterface
196
    {
197 1
        return $this->loadedMap()->filter($predicate);
198
    }
199
200
    /**
201
     * {@inheritdoc}
202
     */
203 1
    public function foreach(callable $function): MapInterface
204
    {
205 1
        return $this->loadedMap()->foreach($function);
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211 1
    public function groupBy(callable $discriminator): MapInterface
212
    {
213 1
        return $this->loadedMap()->groupBy($discriminator);
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219 1
    public function keys(): SetInterface
220
    {
221 1
        return $this->loadedMap()->keys();
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227 2
    public function values(): StreamInterface
228
    {
229 2
        return $this->loadedMap()->values();
230
    }
231
232
    /**
233
     * {@inheritdoc}
234
     */
235 1
    public function map(callable $function): MapInterface
236
    {
237 1
        return $this->loadedMap()->map($function);
238
    }
239
240
    /**
241
     * {@inheritdoc}
242
     */
243 1
    public function join(string $separator): Str
244
    {
245 1
        return $this->loadedMap()->join($separator);
246
    }
247
248
    /**
249
     * {@inheritdoc}
250
     */
251 1
    public function remove($key): MapInterface
252
    {
253 1
        return $this->loadedMap()->remove($key);
254
    }
255
256
    /**
257
     * {@inheritdoc}
258
     */
259 2
    public function merge(MapInterface $map): MapInterface
260
    {
261 2
        if ($map instanceof self && !$this->loaded && !$map->loaded) {
262 1
            $self = clone $this;
263 1
            $self->values = $this->values->merge($map->values);
264
265 1
            return $self;
266
        }
267
268 1
        return $this->loadedMap()->merge($map);
269
    }
270
271
    /**
272
     * {@inheritdoc}
273
     */
274 1
    public function partition(callable $predicate): MapInterface
275
    {
276 1
        return $this->loadedMap()->partition($predicate);
277
    }
278
279
    /**
280
     * {@inheritdoc}
281
     */
282 1
    public function reduce($carry, callable $reducer)
283
    {
284 1
        return $this->loadedMap()->reduce($carry, $reducer);
285
    }
286
287 25
    private function load($value)
288
    {
289 25
        if ($value instanceof Lazy) {
290 23
            return $value->load();
291
        }
292
293 4
        return $value;
294
    }
295
296 24
    private function loadedMap(): Base
297
    {
298 24
        return $this->loaded ?? $this->loaded = $this->values->reduce(
299 24
            $this->clear(),
300 24
            function(Base $map, $key, $value): Base {
301 24
                return $map->put(
302 24
                    $this->load($key),
303 24
                    $this->load($value)
304
                );
305 24
            }
306
        );
307
    }
308
}
309