Passed
Push — version-4 ( d98195...afc63d )
by Sebastian
02:40
created

ArrayListTrait::intersect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
1
<?php
2
declare(strict_types=1);
3
/*
4
 * Copyright (C) 2018 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;
13
14
use Seboettg\Collection\Lists\ListFeatures\ListAccessTrait;
15
use Seboettg\Collection\Lists\MapFeatures\MapFeaturesTrait;
16
use Seboettg\Collection\NativePhp\IteratorTrait;
17
use function Seboettg\Collection\Assert\assertStringable;
18
19
/**
20
 * @property array $array Base array of this data structure
21
 */
22
trait ArrayListTrait
23
{
24
    use IteratorTrait;
25
    use MapFeaturesTrait;
26
    use ListAccessTrait;
27
28
    /**
29
     * flush array list
30
     *
31
     * @return ListInterface|ArrayListTrait
32
     */
33 1
    public function clear(): void
34
    {
35 1
        unset($this->array);
36 1
        $this->array = [];
37 1
    }
38
39
    /**
40
     * Adds the specified element to the end of this list.
41
     *
42
     * @param mixed $element
43
     */
44 13
    public function add($element): void
45
    {
46 13
        end($this->array);
47 13
        $this->array[] = $element;
48 13
    }
49
50
    /**
51
     * @inheritDoc
52
     */
53 1
    public function addAll(iterable $elements): void
54
    {
55 1
        foreach ($elements as $element) {
56 1
            $this->add($element);
57
        }
58 1
    }
59
60
    /**
61
     * @param $key
62
     * @return ListInterface|ArrayListTrait
63
     */
64 1
    public function remove($key): ListInterface
65
    {
66 1
        unset($this->array[$key]);
67 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Seboettg\Collection\Lists\ArrayListTrait which is incompatible with the type-hinted return Seboettg\Collection\Lists\ListInterface.
Loading history...
68
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 2
    public function contains($value): bool
74
    {
75 2
        $result = in_array($value, $this->array, true);
76 2
        return ($result !== false);
77
    }
78
79
    /**
80
     * @inheritDoc
81
     * @see http://php.net/manual/en/function.shuffle.php
82
     * @return ListInterface
83
     */
84 1
    public function shuffle(): ListInterface
85
    {
86 1
        shuffle($this->array);
87 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Seboettg\Collection\Lists\ArrayListTrait which is incompatible with the type-hinted return Seboettg\Collection\Lists\ListInterface.
Loading history...
88
    }
89
90
    /**
91
     * @inheritDoc
92
     * @param callable $predicate|null
93
     * @param bool $preserveKeys
94
     * @return ListInterface|ArrayListTrait
95
     */
96 4
    public function filter(?callable $predicate = null, bool $preserveKeys = false): ListInterface
97
    {
98 4
        $list = emptyList();
99 4
        $filtered = $predicate == null ? array_filter($this->array) : array_filter($this->array, $predicate);
100 4
        $list->setArray(
101 4
            $preserveKeys ? $filtered : array_values($filtered)
102
        );
103 4
        return $list;
104
    }
105
106
    /**
107
     * @param array $array
108
     */
109 22
    public function setArray(array $array): void
110
    {
111 22
        $this->replace($array);
112 22
    }
113
114
    /**
115
     * @param array $data
116
     */
117 24
    public function replace(array $data): void
118
    {
119 24
        $this->array = $data;
120 24
    }
121
122
    /**
123
     * returns a new ArrayList containing all the elements of this ArrayList after applying the callback function to each one.
124
     * @param callable $mapFunction
125
     * @return ListInterface|ArrayListTrait
126
     */
127 7
    public function map(callable $mapFunction): ListInterface
128
    {
129 7
        $list = emptyList();
130 7
        foreach ($this as $value) {
131 7
            $list->add($mapFunction($value));
132
        }
133 6
        return $list;
134
    }
135
136
    /**
137
     * @inheritDoc
138
     * @param callable $mapFunction
139
     * @return ListInterface
140
     */
141 1
    public function mapNotNull(callable $mapFunction): ListInterface
142
    {
143 1
        $list = $this->map($mapFunction);
144 1
        return $list->filter();
145
    }
146
147
    /**
148
     * Returns a new ArrayList containing a one-dimensional array of all elements of this ArrayList. Keys are going lost.
149
     * @return ListInterface
150
     */
151 1
    public function flatten(): ListInterface
152
    {
153 1
        $flattenedArray = [];
154
        array_walk_recursive($this->array, function ($item) use (&$flattenedArray) {
155 1
            $flattenedArray[] = $item;
156 1
        });
157 1
        return listOf(...$flattenedArray);
158
    }
159
160
    /**
161
     * @inheritDoc
162
     * @param callable $collectFunction
163
     * @return mixed
164
     */
165 1
    public function collect(callable $collectFunction)
166
    {
167 1
        return $collectFunction($this->array);
168
    }
169
170
    /**
171
     * @inheritDoc
172
     * @param string $delimiter
173
     * @param string $prefix
174
     * @param string $suffix
175
     * @return string
176
     */
177 4
    public function joinToString(string $delimiter, string $prefix = null, string $suffix = null): string
178
    {
179
        $result = implode($delimiter, $this->map(function ($item) {
180 4
            assertStringable($item, "Elements in list must be convertible to string in order to use joinToString.");
181 3
            return strval($item);
182 4
        })->toArray());
183 3
        if ($prefix !== null) {
184
            $result = $prefix . $result;
185
        }
186 3
        if ($suffix !== null) {
187
            $result = $result . $suffix;
188
        }
189 3
        return $result;
190
    }
191
192
    /**
193
     * @inheritDoc
194
     * @deprecated use joinToString instead
195
     */
196 1
    public function collectToString(string $delimiter): string
197
    {
198 1
        return $this->joinToString($delimiter);
199
    }
200
201
    /**
202
     * @inheritDoc
203
     * @return int
204
     */
205 8
    public function count(): int
206
    {
207 8
        return count($this->array);
208
    }
209
210
    /**
211
     * @inheritDoc
212
     */
213
    public function size(): int
214
    {
215
        return $this->count();
216
    }
217
218
    /**
219
     * @inheritDoc
220
     * @param iterable<scalar> $keys
221
     * @param iterable
222
     */
223
    public function minus(iterable $values): ListInterface
224
    {
225
        if (!$values instanceof ListInterface) {
226
            $valuesList = emptyList();
227
            $valuesList->setArray(is_array($values) ?? $values->toArray());
0 ignored issues
show
Bug introduced by
It seems like is_array($values) ?? $values->toArray() can also be of type boolean; however, parameter $array of anonymous//src/Lists/Functions.php$0::setArray() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

227
            $valuesList->setArray(/** @scrutinizer ignore-type */ is_array($values) ?? $values->toArray());
Loading history...
228
        } else {
229
            $valuesList = $values;
230
        }
231
        $newInstance = emptyList();
232
        foreach ($this->array as $value) {
233
            if (!$valuesList->contains($value)) {
234
                $newInstance->add($value);
235
            }
236
        }
237
        return $newInstance;
238
    }
239
240
241
242
    /**
243
     * @inheritDoc
244
     */
245
    public function intersect(ListInterface $list): ListInterface
246
    {
247
        $newInstance = emptyList();
248
        $newInstance->setArray(array_intersect($this->array, $list->array));
0 ignored issues
show
Bug introduced by
Accessing array on the interface Seboettg\Collection\Lists\ListInterface suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
249
        return $newInstance;
250
    }
251
252
    /**
253
     * @inheritDoc
254
     * @param callable $predicate
255
     * @return Tuple<ListInterface, ListInterface>
256
     */
257
    public function partition(callable $predicate): Tuple
258
    {
259
        $tuple = new Tuple(
260
            emptyList(),
261
            emptyList()
262
        );
263
        $tuple->getFirst()->append(array_filter($this->array, $predicate));
264
        $tuple->getSecond()->append($this->minus($tuple->getFirst()));
265
        return $tuple;
266
    }
267
268
269
    public function plus(iterable $other): ListInterface
270
    {
271
        $list = listOf(...$this->array);
272
        $list->addAll($other);
273
        return $list;
274
    }
275
276
    public function union(ListInterface $other): ListInterface
277
    {
278
        return $this->plus($other);
279
    }
280
281
    public function subtract(ListInterface $other): ListInterface
282
    {
283
        $list = emptyList();
284
        foreach ($this->array as $element) {
285
            if (!$other->contains($element)) {
286
                $list->add($element);
287
            }
288
        }
289
        return $list;
290
    }
291
292
    public function any(callable $predicate): bool
293
    {
294
        return $this->filter($predicate)->count() > 1;
295
    }
296
297
    public function all(callable $predicate): bool
298
    {
299
        return $this->count() === $this->filter($predicate)->count();
300
    }
301
302
    /**
303
     * @inheritDoc
304
     */
305
    public function chunk(int $size): ListInterface
306
    {
307
        $listOfChunks = emptyList();
308
        $arrayChunks = array_chunk($this->array, $size);
309
        foreach ($arrayChunks as $arrayChunk) {
310
            $listOfChunks->add(listOf(...$arrayChunk));
311
        }
312
        return $listOfChunks;
313
    }
314
315
    public function distinct(): ListInterface
316
    {
317
        return listOf(...array_unique($this->array));
318
    }
319
320
    /**
321
     * @inheritDoc
322
     */
323 4
    public function forEach(callable $action): void
324
    {
325 4
        foreach ($this->array as $element) {
326 4
            $action($element);
327
        }
328 4
    }
329
330
    /**
331
     * @inheritDoc
332
     */
333
    public function getOrElse(int $index, callable $defaultValue)
334
    {
335
        if ($this->array[$index] !== null) {
336
            return $this->array[$index];
337
        }
338
        return $defaultValue();
339
    }
340
341
    /**
342
     * @inheritDoc
343
     * @param int $fromIndex
344
     * @param int $toIndex
345
     * @return ListInterface
346
     */
347
    public function subList(int $fromIndex, int $toIndex): ListInterface
348
    {
349
        $list = emptyList();
350
        for ($i = $fromIndex; $i < $toIndex; ++$i) {
351
            if (isset($this->array[$i])) {
352
                $list->add($this->array[$i]);
353
            }
354
        }
355
        return $list;
356
    }
357
358
    /**
359
     * Return first element of this list that matches the matchingCondition
360
     *
361
     * @param callable $matchingCondition
362
     * @return mixed|null
363
     */
364
    public function searchBy(callable $matchingCondition)
365
    {
366
        $list = listOf(...array_filter($this->array));
367
        return $list->filter($matchingCondition)->first();
368
    }
369
370
    public function isEmpty(): bool
371
    {
372
        return $this->count() === 0;
373
    }
374
375
    /**
376
     * {@inheritDoc}
377
     */
378 9
    public function toArray(): array
379
    {
380 9
        return $this->array;
381
    }
382
}
383