GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( f46a23...825633 )
by Baptiste
04:48
created

DoubleIndex::groupBy()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 22
nc 6
nop 1
dl 0
loc 38
ccs 22
cts 22
cp 1
crap 5
rs 9.2568
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable\Map;
5
6
use Innmind\Immutable\{
7
    MapInterface,
8
    Map,
9
    Type,
10
    Str,
11
    Stream,
12
    StreamInterface,
13
    SetInterface,
14
    Set,
15
    Pair,
16
    Exception\InvalidArgumentException,
17
    Exception\LogicException,
18
    Exception\ElementNotFoundException,
19
    Exception\GroupEmptyMapException
20
};
21
22
final class DoubleIndex implements MapInterface
23
{
24
    private $keyType;
25
    private $valueType;
26
    private $keySpecification;
27
    private $valueSpecification;
28
    private $keys;
29
    private $values;
30
    private $pairs;
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 80
    public function __construct(string $keyType, string $valueType)
36
    {
37 80
        $this->keySpecification = Type::of($keyType);
38 80
        $this->valueSpecification = Type::of($valueType);
39 80
        $this->keyType = new Str($keyType);
40 80
        $this->valueType = new Str($valueType);
41 80
        $this->keys = new Stream($keyType);
42 80
        $this->values = new Stream($valueType);
43 80
        $this->pairs = new Stream(Pair::class);
44 80
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 36
    public function keyType(): Str
50
    {
51 36
        return $this->keyType;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 32
    public function valueType(): Str
58
    {
59 32
        return $this->valueType;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 14
    public function size(): int
66
    {
67 14
        return $this->keys->size();
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 4
    public function count(): int
74
    {
75 4
        return $this->keys->count();
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81 2
    public function current()
82
    {
83 2
        return $this->values->current();
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 2
    public function key()
90
    {
91 2
        return $this->keys->current();
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97 2
    public function next()
98
    {
99 2
        $this->keys->next();
100 2
        $this->values->next();
101 2
        $this->pairs->next();
102 2
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107 2
    public function rewind()
108
    {
109 2
        $this->keys->rewind();
110 2
        $this->values->rewind();
111 2
        $this->pairs->rewind();
112 2
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 2
    public function valid()
118
    {
119 2
        return $this->keys->valid();
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125 2
    public function offsetExists($offset): bool
126
    {
127 2
        return $this->keys->contains($offset);
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133 6
    public function offsetGet($offset)
134
    {
135 6
        return $this->get($offset);
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141 2
    public function offsetSet($offset, $value)
142
    {
143 2
        throw new LogicException('You can\'t modify a map');
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149 2
    public function offsetUnset($offset)
150
    {
151 2
        throw new LogicException('You can\'t modify a map');
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 66
    public function put($key, $value): MapInterface
158
    {
159 66
        $this->keySpecification->validate($key);
160 64
        $this->valueSpecification->validate($value);
161
162 60
        $map = clone $this;
163
164 60
        if ($this->keys->contains($key)) {
165 6
            $index = $this->keys->indexOf($key);
166 6
            $map->values = $this->values->take($index)
167 6
                ->add($value)
168 6
                ->append($this->values->drop($index + 1));
169 6
            $map->pairs = $this->pairs->take($index)
170 6
                ->add(new Pair($key, $value))
171 6
                ->append($this->pairs->drop($index + 1));
172
        } else {
173 60
            $map->keys = $this->keys->add($key);
174 60
            $map->values = $this->values->add($value);
175 60
            $map->pairs = $this->pairs->add(new Pair($key, $value));
176
        }
177
178 60
        return $map;
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184 36
    public function get($key)
185
    {
186 36
        if (!$this->keys->contains($key)) {
187 4
            throw new ElementNotFoundException;
188
        }
189
190 32
        return $this->values->get(
191 32
            $this->keys->indexOf($key)
192
        );
193
    }
194
195
    /**
196
     * {@inheritdoc}
197
     */
198 6
    public function contains($key): bool
199
    {
200 6
        return $this->keys->contains($key);
201
    }
202
203
    /**
204
     * {@inheritdoc}
205
     */
206 14
    public function clear(): MapInterface
207
    {
208 14
        $map = clone $this;
209 14
        $map->keys = $this->keys->clear();
210 14
        $map->values = $this->values->clear();
211 14
        $map->pairs = $this->pairs->clear();
212
213 14
        return $map;
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     */
219 4
    public function equals(MapInterface $map): bool
220
    {
221 4
        if (!$map->keys()->equals($this->keys())) {
222 2
            return false;
223
        }
224
225 4
        foreach ($this->pairs as $pair) {
226 4
            if ($map->get($pair->key()) !== $pair->value()) {
227 4
                return false;
228
            }
229
        }
230
231 2
        return true;
232
    }
233
234
    /**
235
     * {@inheritdoc}
236
     */
237 2
    public function filter(callable $predicate): MapInterface
238
    {
239 2
        $map = $this->clear();
240
241 2
        foreach ($this->pairs as $pair) {
242 2
            if ($predicate($pair->key(), $pair->value()) === true) {
243 2
                $map->keys = $map->keys->add($pair->key());
244 2
                $map->values = $map->values->add($pair->value());
245 2
                $map->pairs = $map->pairs->add($pair);
246
            }
247
        }
248
249 2
        return $map;
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255 2
    public function foreach(callable $function): MapInterface
256
    {
257 2
        foreach ($this->pairs as $pair) {
258 2
            $function($pair->key(), $pair->value());
259
        }
260
261 2
        return $this;
262
    }
263
264
    /**
265
     * {@inheritdoc}
266
     */
267 4
    public function groupBy(callable $discriminator): MapInterface
268
    {
269 4
        if ($this->size() === 0) {
270 2
            throw new GroupEmptyMapException;
271
        }
272
273 2
        $map = null;
274
275 2
        foreach ($this->pairs as $pair) {
276 2
            $key = $discriminator($pair->key(), $pair->value());
277
278 2
            if ($map === null) {
279 2
                $map = new Map(
280 2
                    Type::determine($key),
281 2
                    MapInterface::class
282
                );
283
            }
284
285 2
            if ($map->contains($key)) {
286 2
                $map = $map->put(
287 2
                    $key,
288 2
                    $map->get($key)->put(
289 2
                        $pair->key(),
290 2
                        $pair->value()
291
                    )
292
                );
293
            } else {
294 2
                $map = $map->put(
295 2
                    $key,
296 2
                    $this->clear()->put(
297 2
                        $pair->key(),
298 2
                        $pair->value()
299
                    )
300
                );
301
            }
302
        }
303
304 2
        return $map;
305
    }
306
307
    /**
308
     * {@inheritdoc}
309
     */
310 20
    public function keys(): SetInterface
311
    {
312 20
        return Set::of((string) $this->keyType, ...$this->keys);
313
    }
314
315
    /**
316
     * {@inheritdoc}
317
     */
318 12
    public function values(): StreamInterface
319
    {
320 12
        return $this->values;
321
    }
322
323
    /**
324
     * {@inheritdoc}
325
     */
326 6
    public function map(callable $function): MapInterface
327
    {
328 6
        $map = $this->clear();
329
330 6
        foreach ($this->pairs as $pair) {
331 6
            $return = $function(
332 6
                $pair->key(),
333 6
                $pair->value()
334
            );
335
336 6
            if ($return instanceof Pair) {
337 4
                $key = $return->key();
338 4
                $value = $return->value();
339
            } else {
340 4
                $key = $pair->key();
341 4
                $value = $return;
342
            }
343
344 6
            $map = $map->put($key, $value);
345
        }
346
347 2
        return $map;
348
    }
349
350
    /**
351
     * {@inheritdoc}
352
     */
353 2
    public function join(string $separator): Str
354
    {
355 2
        return $this->values->join($separator);
356
    }
357
358
    /**
359
     * {@inheritdoc}
360
     */
361 2
    public function remove($key): MapInterface
362
    {
363 2
        if (!$this->contains($key)) {
364 2
            return $this;
365
        }
366
367 2
        $index = $this->keys->indexOf($key);
368 2
        $map = clone $this;
369 2
        $map->keys = $this
370 2
            ->keys
371 2
            ->slice(0, $index)
372 2
            ->append($this->keys->slice($index + 1, $this->keys->size()));
373 2
        $map->values = $this
374 2
            ->values
375 2
            ->slice(0, $index)
376 2
            ->append($this->values->slice($index + 1, $this->values->size()));
377 2
        $map->pairs = $this
378 2
            ->pairs
379 2
            ->slice(0, $index)
380 2
            ->append($this->pairs->slice($index + 1, $this->pairs->size()));
381
382 2
        return $map;
383
    }
384
385
    /**
386
     * {@inheritdoc}
387
     */
388 4
    public function merge(MapInterface $map): MapInterface
389
    {
390
        if (
391 4
            !$this->keyType()->equals($map->keyType()) ||
392 4
            !$this->valueType()->equals($map->valueType())
393
        ) {
394 2
            throw new InvalidArgumentException(
395 2
                'The 2 maps does not reference the same types'
396
            );
397
        }
398
399 2
        return $map->reduce(
400 2
            $this,
401 2
            function(self $carry, $key, $value): self {
402 2
                return $carry->put($key, $value);
403 2
            }
404
        );
405
    }
406
407
    /**
408
     * {@inheritdoc}
409
     */
410 2
    public function partition(callable $predicate): MapInterface
411
    {
412 2
        $truthy = $this->clear();
413 2
        $falsy = $this->clear();
414
415 2
        foreach ($this->pairs as $pair) {
416 2
            $return = $predicate(
417 2
                $pair->key(),
418 2
                $pair->value()
419
            );
420
421 2
            if ($return === true) {
422 2
                $truthy = $truthy->put($pair->key(), $pair->value());
423
            } else {
424 2
                $falsy = $falsy->put($pair->key(), $pair->value());
425
            }
426
        }
427
428 2
        return Map::of('bool', MapInterface::class)
429 2
            (true, $truthy)
430 2
            (false, $falsy);
431
    }
432
433
    /**
434
     * {@inheritdoc}
435
     */
436 4
    public function reduce($carry, callable $reducer)
437
    {
438 4
        foreach ($this->pairs as $pair) {
439 4
            $carry = $reducer($carry, $pair->key(), $pair->value());
440
        }
441
442 4
        return $carry;
443
    }
444
}
445