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.
Completed
Push — develop ( 870d79...a1e45f )
by Baptiste
05:29
created

DoubleIndex   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 347
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 139
c 1
b 0
f 0
dl 0
loc 347
ccs 150
cts 150
cp 1
rs 9.1199
wmc 41

23 Methods

Rating   Name   Duplication   Size   Complexity  
A size() 0 3 1
A keyType() 0 3 1
A __construct() 0 9 1
A valueType() 0 3 1
A count() 0 3 1
A put() 0 22 2
A clearMap() 0 3 1
A equals() 0 13 4
A partition() 0 21 3
A get() 0 8 2
A foreach() 0 4 2
A map() 0 22 3
A contains() 0 3 1
A values() 0 3 1
A remove() 0 22 2
A keys() 0 3 1
A reduce() 0 7 2
A join() 0 3 1
A empty() 0 3 1
A filter() 0 13 3
A clear() 0 8 1
A merge() 0 6 1
A groupBy() 0 38 5

How to fix   Complexity   

Complex Class

Complex classes like DoubleIndex often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DoubleIndex, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable\Map;
5
6
use Innmind\Immutable\{
7
    Map,
8
    Type,
9
    Str,
10
    Sequence,
11
    Set,
12
    Pair,
13
    ValidateArgument,
14
    Exception\LogicException,
15
    Exception\ElementNotFound,
16
    Exception\CannotGroupEmptyStructure,
17
};
18
19
/**
20
 * {@inheritdoc}
21
 */
22
final class DoubleIndex implements Implementation
23
{
24
    private string $keyType;
25
    private string $valueType;
26
    private ValidateArgument $validateKey;
27
    private ValidateArgument $validateValue;
28
    private Sequence $keys;
29
    private Sequence $values;
30
    private Sequence $pairs;
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 38
    public function __construct(string $keyType, string $valueType)
36
    {
37 38
        $this->validateKey = Type::of($keyType);
38 38
        $this->validateValue = Type::of($valueType);
39 38
        $this->keyType = $keyType;
40 38
        $this->valueType = $valueType;
41 38
        $this->keys = Sequence::of($keyType);
42 38
        $this->values = Sequence::of($valueType);
43 38
        $this->pairs = Sequence::of(Pair::class);
44 38
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 18
    public function keyType(): string
50
    {
51 18
        return $this->keyType;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 18
    public function valueType(): string
58
    {
59 18
        return $this->valueType;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 8
    public function size(): int
66
    {
67 8
        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 33
    public function put($key, $value): Implementation
82
    {
83 33
        ($this->validateKey)($key, 1);
84 32
        ($this->validateValue)($value, 2);
85
86 31
        $map = clone $this;
87
88 31
        if ($this->keys->contains($key)) {
89 4
            $index = $this->keys->indexOf($key);
90 4
            $map->values = $this->values->take($index)
91 4
                ->add($value)
92 4
                ->append($this->values->drop($index + 1));
93 4
            $map->pairs = $this->pairs->take($index)
94 4
                ->add(new Pair($key, $value))
95 4
                ->append($this->pairs->drop($index + 1));
96
        } else {
97 31
            $map->keys = $this->keys->add($key);
98 31
            $map->values = $this->values->add($value);
99 31
            $map->pairs = $this->pairs->add(new Pair($key, $value));
100
        }
101
102 31
        return $map;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 18
    public function get($key)
109
    {
110 18
        if (!$this->keys->contains($key)) {
111 1
            throw new ElementNotFound($key);
112
        }
113
114 17
        return $this->values->get(
115 17
            $this->keys->indexOf($key)
116
        );
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 3
    public function contains($key): bool
123
    {
124 3
        return $this->keys->contains($key);
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 5
    public function clear(): Implementation
131
    {
132 5
        $map = clone $this;
133 5
        $map->keys = $this->keys->clear();
134 5
        $map->values = $this->values->clear();
135 5
        $map->pairs = $this->pairs->clear();
136
137 5
        return $map;
138
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 3
    public function equals(Implementation $map): bool
144
    {
145 3
        if (!$map->keys()->equals($this->keys())) {
146 1
            return false;
147
        }
148
149 3
        foreach ($this->pairs->toArray() as $pair) {
150 3
            if ($map->get($pair->key()) !== $pair->value()) {
151 3
                return false;
152
            }
153
        }
154
155 1
        return true;
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161 1
    public function filter(callable $predicate): Implementation
162
    {
163 1
        $map = $this->clear();
164
165 1
        foreach ($this->pairs->toArray() as $pair) {
166 1
            if ($predicate($pair->key(), $pair->value()) === true) {
167 1
                $map->keys = $map->keys->add($pair->key());
168 1
                $map->values = $map->values->add($pair->value());
169 1
                $map->pairs = $map->pairs->add($pair);
170
            }
171
        }
172
173 1
        return $map;
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179 1
    public function foreach(callable $function): void
180
    {
181 1
        foreach ($this->pairs->toArray() as $pair) {
182 1
            $function($pair->key(), $pair->value());
183
        }
184 1
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189 2
    public function groupBy(callable $discriminator): Map
190
    {
191 2
        if ($this->size() === 0) {
192 1
            throw new CannotGroupEmptyStructure;
193
        }
194
195 1
        $map = null;
196
197 1
        foreach ($this->pairs->toArray() as $pair) {
198 1
            $key = $discriminator($pair->key(), $pair->value());
199
200 1
            if ($map === null) {
201 1
                $map = Map::of(
202 1
                    Type::determine($key),
203 1
                    Map::class
204
                );
205
            }
206
207 1
            if ($map->contains($key)) {
208 1
                $map = $map->put(
209 1
                    $key,
210 1
                    $map->get($key)->put(
211 1
                        $pair->key(),
212 1
                        $pair->value()
213
                    )
214
                );
215
            } else {
216 1
                $map = $map->put(
217 1
                    $key,
218 1
                    $this->clearMap()->put(
219 1
                        $pair->key(),
220 1
                        $pair->value()
221
                    )
222
                );
223
            }
224
        }
225
226 1
        return $map;
227
    }
228
229
    /**
230
     * {@inheritdoc}
231
     */
232 11
    public function keys(): Set
233
    {
234 11
        return Set::of($this->keyType, ...$this->keys->toArray());
235
    }
236
237
    /**
238
     * {@inheritdoc}
239
     */
240 7
    public function values(): Sequence
241
    {
242 7
        return $this->values;
243
    }
244
245
    /**
246
     * {@inheritdoc}
247
     */
248 3
    public function map(callable $function): Implementation
249
    {
250 3
        $map = $this->clear();
251
252 3
        foreach ($this->pairs->toArray() as $pair) {
253 3
            $return = $function(
254 3
                $pair->key(),
255 3
                $pair->value()
256
            );
257
258 3
            if ($return instanceof Pair) {
259 2
                $key = $return->key();
260 2
                $value = $return->value();
261
            } else {
262 2
                $key = $pair->key();
263 2
                $value = $return;
264
            }
265
266 3
            $map = $map->put($key, $value);
267
        }
268
269 1
        return $map;
270
    }
271
272
    /**
273
     * {@inheritdoc}
274
     */
275 1
    public function join(string $separator): Str
276
    {
277 1
        return $this->values->join($separator);
278
    }
279
280
    /**
281
     * {@inheritdoc}
282
     */
283 1
    public function remove($key): Implementation
284
    {
285 1
        if (!$this->contains($key)) {
286 1
            return $this;
287
        }
288
289 1
        $index = $this->keys->indexOf($key);
290 1
        $map = clone $this;
291 1
        $map->keys = $this
292 1
            ->keys
293 1
            ->slice(0, $index)
294 1
            ->append($this->keys->slice($index + 1, $this->keys->size()));
295 1
        $map->values = $this
296 1
            ->values
297 1
            ->slice(0, $index)
298 1
            ->append($this->values->slice($index + 1, $this->values->size()));
299 1
        $map->pairs = $this
300 1
            ->pairs
301 1
            ->slice(0, $index)
302 1
            ->append($this->pairs->slice($index + 1, $this->pairs->size()));
303
304 1
        return $map;
305
    }
306
307
    /**
308
     * {@inheritdoc}
309
     */
310 2
    public function merge(Implementation $map): Implementation
311
    {
312 2
        return $map->reduce(
313 2
            $this,
314
            function(self $carry, $key, $value): self {
315 2
                return $carry->put($key, $value);
316 2
            }
317
        );
318
    }
319
320
    /**
321
     * {@inheritdoc}
322
     */
323 1
    public function partition(callable $predicate): Map
324
    {
325 1
        $truthy = $this->clearMap();
326 1
        $falsy = $this->clearMap();
327
328 1
        foreach ($this->pairs->toArray() as $pair) {
329 1
            $return = $predicate(
330 1
                $pair->key(),
331 1
                $pair->value()
332
            );
333
334 1
            if ($return === true) {
335 1
                $truthy = $truthy->put($pair->key(), $pair->value());
336
            } else {
337 1
                $falsy = $falsy->put($pair->key(), $pair->value());
338
            }
339
        }
340
341 1
        return Map::of('bool', Map::class)
342 1
            (true, $truthy)
343 1
            (false, $falsy);
344
    }
345
346
    /**
347
     * {@inheritdoc}
348
     */
349 3
    public function reduce($carry, callable $reducer)
350
    {
351 3
        foreach ($this->pairs->toArray() as $pair) {
352 3
            $carry = $reducer($carry, $pair->key(), $pair->value());
353
        }
354
355 3
        return $carry;
356
    }
357
358 1
    public function empty(): bool
359
    {
360 1
        return $this->pairs->empty();
361
    }
362
363
    /**
364
     * @return Map<T, S>
365
     */
366 2
    private function clearMap(): Map
367
    {
368 2
        return Map::of($this->keyType, $this->valueType);
369
    }
370
}
371