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 — develop ( c3b70c...588978 )
by Baptiste
05:12
created

Set::toArray()   A

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
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable;
5
6
use Innmind\Immutable\Exception\InvalidArgumentException;
7
8
final class Set implements \Countable
9
{
10
    private string $type;
11
    private SpecificationInterface $spec;
12
    private Stream $values;
13
14
    /**
15
     * {@inheritdoc}
16
     */
17 53
    public function __construct(string $type)
18
    {
19 53
        $this->type = $type;
20 53
        $this->spec = Type::of($type);
21 53
        $this->values = new Stream($type);
22 53
    }
23
24 32
    public static function of(string $type, ...$values): self
25
    {
26 32
        $self = new self($type);
27 32
        $self->values = Stream::of($type, ...$values)->distinct();
28
29 32
        return $self;
30
    }
31
32 16
    public function isOfType(string $type): bool
33
    {
34 16
        return $this->type === $type;
35
    }
36
37
    /**
38
     * Return the type of this set
39
     */
40 13
    public function type(): string
41
    {
42 13
        return $this->type;
43
    }
44
45 11
    public function size(): int
46
    {
47 11
        return $this->values->size();
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 1
    public function count(): int
54
    {
55 1
        return $this->values->size();
56
    }
57
58 42
    public function toArray(): array
59
    {
60 42
        return $this->values->toArray();
61
    }
62
63
    /**
64
     * Intersect this set with the given one
65
     *
66
     * @param self<T> $set
67
     *
68
     * @throws InvalidArgumentException If the sets are not of the same type
69
     *
70
     * @return self<T>
71
     */
72 11
    public function intersect(self $set): self
73
    {
74 11
        $this->validate($set);
75
76 10
        $newSet = clone $this;
77 10
        $newSet->values = $this->values->intersect(
78 10
            Stream::of($this->type, ...$set->toArray())
79
        );
80
81 10
        return $newSet;
82
    }
83
84
    /**
85
     * Add a element to the set
86
     *
87
     * @param T $element
88
     *
89
     * @return self<T>
90
     */
91 26
    public function add($element): self
92
    {
93 26
        $this->spec->validate($element);
94
95 25
        if ($this->contains($element)) {
96 2
            return $this;
97
        }
98
99 25
        $set = clone $this;
100 25
        $set->values = $this->values->add($element);
101
102 25
        return $set;
103
    }
104
105
    /**
106
     * Check if the set contains the given element
107
     *
108
     * @param T $element
109
     */
110 25
    public function contains($element): bool
111
    {
112 25
        return $this->values->contains($element);
113
    }
114
115
    /**
116
     * Remove the element from the set
117
     *
118
     * @param T $element
119
     *
120
     * @return self<T>
121
     */
122 1
    public function remove($element): self
123
    {
124 1
        if (!$this->contains($element)) {
125
            return $this;
126
        }
127
128 1
        $index = $this->values->indexOf($element);
129 1
        $set = clone $this;
130 1
        $set->values = $this
131 1
            ->values
132 1
            ->clear()
133 1
            ->append($this->values->slice(0, $index))
134 1
            ->append($this->values->slice($index + 1, $this->size()));
135
136 1
        return $set;
137
    }
138
139
    /**
140
     * Return the diff between this set and the given one
141
     *
142
     * @param self<T> $set
143
     *
144
     * @return self<T>
145
     */
146 2
    public function diff(self $set): self
147
    {
148 2
        $this->validate($set);
149
150 1
        $newSet = clone $this;
151 1
        $newSet->values = $this->values->diff(
152 1
            Stream::of($this->type, ...$set->toArray())
153
        );
154
155 1
        return $newSet;
156
    }
157
158
    /**
159
     * Check if the given set is identical to this one
160
     *
161
     * @param self<T> $set
162
     */
163 10
    public function equals(self $set): bool
164
    {
165 10
        $this->validate($set);
166
167 9
        if ($this->size() !== $set->size()) {
168 2
            return false;
169
        }
170
171 9
        return $this->intersect($set)->size() === $this->size();
172
    }
173
174
    /**
175
     * Return all elements that satisfy the given predicate
176
     *
177
     * @param callable(T): bool $predicate
178
     *
179
     * @return self<T>
180
     */
181 1
    public function filter(callable $predicate): self
182
    {
183 1
        $set = clone $this;
184 1
        $set->values = $this->values->filter($predicate);
185
186 1
        return $set;
187
    }
188
189
    /**
190
     * Apply the given function to all elements of the set
191
     *
192
     * @param callable(T): void $function
193
     *
194
     * @return self<T>
195
     */
196 1
    public function foreach(callable $function): void
197
    {
198 1
        $this->values->foreach($function);
199 1
    }
200
201
    /**
202
     * Return a new map of pairs grouped by keys determined with the given
203
     * discriminator function
204
     *
205
     * @param callable(T) $discriminator
206
     *
207
     * @return Map<mixed, self<T>>
208
     */
209 1
    public function groupBy(callable $discriminator): Map
210
    {
211 1
        $map = $this->values->groupBy($discriminator);
212
213 1
        return $map->reduce(
214 1
            new Map($map->keyType(), Set::class),
215
            function(Map $carry, $key, Stream $values): Map {
216 1
                $set = $this->clear();
217 1
                $set->values = $values;
218
219 1
                return $carry->put($key, $set);
220 1
            }
221
        );
222
    }
223
224
    /**
225
     * Return a new set by applying the given function to all elements
226
     *
227
     * @param callable(T): T $function
228
     *
229
     * @return self<T>
230
     */
231 2
    public function map(callable $function): self
232
    {
233 2
        return $this->reduce(
234 2
            $this->clear(),
235
            function(self $carry, $value) use ($function): self {
236 2
                return $carry->add($function($value));
237 2
            }
238
        );
239
    }
240
241
    /**
242
     * Return a sequence of 2 sets partitioned according to the given predicate
243
     *
244
     * @param callable(T): bool $predicate
245
     *
246
     * @return Map<bool, self<T>>
247
     */
248 1
    public function partition(callable $predicate): Map
249
    {
250 1
        $truthy = $this->clear();
251 1
        $falsy = $this->clear();
252 1
        $partitions = $this->values->partition($predicate);
253 1
        $truthy->values = $partitions->get(true);
254 1
        $falsy->values = $partitions->get(false);
255
256 1
        return Map::of('bool', Set::class)
257 1
            (true, $truthy)
258 1
            (false, $falsy);
259
    }
260
261
    /**
262
     * Concatenate all elements with the given separator
263
     */
264 1
    public function join(string $separator): Str
265
    {
266 1
        return $this->values->join($separator);
267
    }
268
269
    /**
270
     * Return a sequence sorted with the given function
271
     *
272
     * @param callable(T, T): int $function
273
     *
274
     * @return Stream<T>
275
     */
276 1
    public function sort(callable $function): Stream
277
    {
278 1
        return $this->values->sort($function);
279
    }
280
281
    /**
282
     * Create a new set with elements of both sets
283
     *
284
     * @param self<T> $set
285
     *
286
     * @return self<T>
287
     */
288 2
    public function merge(self $set): self
289
    {
290 2
        $this->validate($set);
291
292 1
        return $set->reduce(
293 1
            $this,
294
            function(self $carry, $value): self {
295 1
                return $carry->add($value);
296 1
            }
297
        );
298
    }
299
300
    /**
301
     * Reduce the set to a single value
302
     *
303
     * @param mixed $carry
304
     * @param callable(mixed, T) $reducer
305
     *
306
     * @return mixed
307
     */
308 4
    public function reduce($carry, callable $reducer)
309
    {
310 4
        return $this->values->reduce($carry, $reducer);
311
    }
312
313
    /**
314
     * Return a set of the same type but without any value
315
     *
316
     * @return self<T>
317
     */
318 4
    public function clear(): self
319
    {
320 4
        $self = clone $this;
321 4
        $self->values = $this->values->clear();
322
323 4
        return $self;
324
    }
325
326 1
    public function empty(): bool
327
    {
328 1
        return $this->values->empty();
329
    }
330
331
    /**
332
     * Make sure the set is compatible with the current one
333
     *
334
     * @throws InvalidArgumentException
335
     */
336 15
    private function validate(self $set): void
337
    {
338 15
        if (!$set->isOfType($this->type)) {
339 4
            throw new InvalidArgumentException(
340 4
                'The 2 sets does not reference the same type'
341
            );
342
        }
343 11
    }
344
}
345