Passed
Push — version-4 ( 84aff8...d98195 )
by Sebastian
02:28
created

ArrayListTrait::partition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 9
ccs 0
cts 7
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\MapFeatures\MapFeaturesTrait;
15
use Seboettg\Collection\NativePhp\IteratorTrait;
16
use function Seboettg\Collection\Assert\assertStringable;
17
18
/**
19
 * @property array $array Base array of this data structure
20
 */
21
trait ArrayListTrait
22
{
23
    use IteratorTrait;
24
    use MapFeaturesTrait;
25
26
    /**
27
     * flush array list
28
     *
29
     * @return ListInterface|ArrayListTrait
30
     */
31 1
    public function clear(): void
32
    {
33 1
        unset($this->array);
34 1
        $this->array = [];
35 1
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 5
    public function get(int $index)
41
    {
42 5
        return $this->array[$index] ?? null;
43
    }
44
45
    /**
46
     * @param $key
47
     * @param $element
48
     * @return void
49
     */
50
    public function set($key, $element): void
51
    {
52
        $this->array[$key] = $element;
53
    }
54
55
    /**
56
     * Adds the specified element to the end of this list.
57
     *
58
     * @param mixed $element
59
     */
60 13
    public function add($element): void
61
    {
62 13
        end($this->array);
63 13
        $this->array[] = $element;
64 13
    }
65
66
    /**
67
     * @inheritDoc
68
     */
69 1
    public function addAll(iterable $elements): void
70
    {
71 1
        foreach ($elements as $element) {
72 1
            $this->add($element);
73
        }
74 1
    }
75
76
    /**
77
     * @param $key
78
     * @return ListInterface|ArrayListTrait
79
     */
80 1
    public function remove($key): ListInterface
81
    {
82 1
        unset($this->array[$key]);
83 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...
84
    }
85
86
    /**
87
     * {@inheritdoc}
88
     */
89 2
    public function contains($value): bool
90
    {
91 2
        $result = in_array($value, $this->array, true);
92 2
        return ($result !== false);
93
    }
94
95
    /**
96
     * Returns the first element
97
     * @return mixed
98
     */
99 1
    public function first()
100
    {
101 1
        if ($this->isEmpty()) {
102
            return null;
103
        }
104 1
        reset($this->array);
105 1
        return $this->array[key($this->array)];
106
    }
107
108
    /**
109
     * Returns the last element
110
     * @return mixed
111
     */
112 1
    public function last()
113
    {
114 1
        $item = end($this->array);
115 1
        reset($this->array);
116 1
        return $item;
117
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122 9
    public function toArray(): array
123
    {
124 9
        return $this->array;
125
    }
126
127
    /**
128
     * Shuffles this list (randomizes the order of the elements in). It uses the PHP function shuffle
129
     * @see http://php.net/manual/en/function.shuffle.php
130
     * @return ListInterface|ArrayListTrait
131
     */
132 1
    public function shuffle(): ListInterface
133
    {
134 1
        shuffle($this->array);
135 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...
136
    }
137
138
    /**
139
     * @inheritDoc
140
     * @param ?callable $predicate
141
     * @param bool $preserveKeys
142
     * @return ListInterface|ArrayListTrait
143
     */
144 4
    public function filter(?callable $predicate = null, bool $preserveKeys = false): ListInterface
145
    {
146 4
        $list = emptyList();
147 4
        $filtered = $predicate == null ? array_filter($this->array) : array_filter($this->array, $predicate);
148 4
        $list->setArray(
149 4
            $preserveKeys ? $filtered : array_values($filtered)
150
        );
151 4
        return $list;
152
    }
153
154
    /**
155
     * @param array $array
156
     */
157 22
    public function setArray(array $array): void
158
    {
159 22
        $this->replace($array);
160 22
    }
161
162
    /**
163
     * @param array $data
164
     */
165 24
    public function replace(array $data): void
166
    {
167 24
        $this->array = $data;
168 24
    }
169
170
    /**
171
     * returns a new ArrayList containing all the elements of this ArrayList after applying the callback function to each one.
172
     * @param callable $mapFunction
173
     * @return ListInterface|ArrayListTrait
174
     */
175 7
    public function map(callable $mapFunction): ListInterface
176
    {
177 7
        $newInstance = emptyList();
178 7
        foreach ($this as $value) {
179 7
            $newInstance->add($mapFunction($value));
180
        }
181 6
        return $newInstance;
182
    }
183
184
    /**
185
     * @inheritDoc
186
     * @param callable $mapFunction
187
     * @return ListInterface
188
     */
189 1
    public function mapNotNull(callable $mapFunction): ListInterface
190
    {
191 1
        $newInstance = $this->map($mapFunction);
192 1
        return $newInstance->filter();
193
    }
194
195
    /**
196
     * Returns a new ArrayList containing a one-dimensional array of all elements of this ArrayList. Keys are going lost.
197
     * @return ListInterface
198
     */
199 1
    public function flatten(): ListInterface
200
    {
201 1
        $flattenedArray = [];
202
        array_walk_recursive($this->array, function ($item) use (&$flattenedArray) {
203 1
            $flattenedArray[] = $item;
204 1
        });
205 1
        return listOf(...$flattenedArray);
206
    }
207
208
    /**
209
     * @inheritDoc
210
     * @param callable $collectFunction
211
     * @return mixed
212
     */
213 1
    public function collect(callable $collectFunction)
214
    {
215 1
        return $collectFunction($this->array);
216
    }
217
218
    /**
219
     * @inheritDoc
220
     * @param string $delimiter
221
     * @param string $prefix
222
     * @param string $suffix
223
     * @return string
224
     */
225 4
    public function joinToString(string $delimiter, string $prefix = null, string $suffix = null): string
226
    {
227
        $result = implode($delimiter, $this->map(function ($item) {
228 4
            assertStringable($item, "Elements in list must be convertible to string in order to use joinToString.");
229 3
            return strval($item);
230 4
        })->toArray());
231 3
        if ($prefix !== null) {
232
            $result = $prefix . $result;
233
        }
234 3
        if ($suffix !== null) {
235
            $result = $result . $suffix;
236
        }
237 3
        return $result;
238
    }
239
240
    /**
241
     * @inheritDoc
242
     * @deprecated use joinToString instead
243
     */
244 1
    public function collectToString(string $delimiter): string
245
    {
246 1
        return $this->joinToString($delimiter);
247
    }
248
249
    /**
250
     * @inheritDoc
251
     * @return int
252
     */
253 9
    public function count(): int
254
    {
255 9
        return count($this->array);
256
    }
257
258
    /**
259
     * @inheritDoc
260
     * @param iterable<scalar> $keys
261
     * @param iterable
262
     */
263
    public function minus(iterable $values): ListInterface
264
    {
265
        if (!$values instanceof ListInterface) {
266
            $valuesList = emptyList();
267
            $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

267
            $valuesList->setArray(/** @scrutinizer ignore-type */ is_array($values) ?? $values->toArray());
Loading history...
268
        } else {
269
            $valuesList = $values;
270
        }
271
        $newInstance = emptyList();
272
        foreach ($this->array as $value) {
273
            if (!$valuesList->contains($value)) {
274
                $newInstance->add($value);
275
            }
276
        }
277
        return $newInstance;
278
    }
279
280
281
282
    /**
283
     * @inheritDoc
284
     */
285
    public function intersect(ListInterface $list): ListInterface
286
    {
287
        $newInstance = emptyList();
288
        $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...
289
        return $newInstance;
290
    }
291
292
    /**
293
     * @inheritDoc
294
     * @param callable $predicate
295
     * @return Tuple<ListInterface, ListInterface>
296
     */
297
    public function partition(callable $predicate): Tuple
298
    {
299
        $tuple = new Tuple(
300
            emptyList(),
301
            emptyList()
302
        );
303
        $tuple->getFirst()->append(array_filter($this->array, $predicate));
304
        $tuple->getSecond()->append($this->minus($tuple->getFirst()));
305
        return $tuple;
306
    }
307
308
309
    public function plus(iterable $other): ListInterface
310
    {
311
        $list = listOf(...$this->array);
312
        $list->addAll($other);
313
        return $list;
314
    }
315
316
    public function union(ListInterface $other): ListInterface
317
    {
318
        return $this->plus($other);
319
    }
320
321
    public function subtract(ListInterface $other): ListInterface
322
    {
323
        $list = emptyList();
324
        foreach ($this->array as $element) {
325
            if (!$other->contains($element)) {
326
                $list->add($element);
327
            }
328
        }
329
        return $list;
330
    }
331
332
    public function any(callable $predicate): bool
333
    {
334
        return $this->filter($predicate)->count() > 1;
335
    }
336
337
    public function all(callable $predicate): bool
338
    {
339
        return $this->count() === $this->filter($predicate)->count();
340
    }
341
342
    /**
343
     * @inheritDoc
344
     */
345
    public function chunk(int $size): ListInterface
346
    {
347
        $listOfChunks = emptyList();
348
        $arrayChunks = array_chunk($this->array, $size);
349
        foreach ($arrayChunks as $arrayChunk) {
350
            $listOfChunks->add(listOf(...$arrayChunk));
351
        }
352
        return $listOfChunks;
353
    }
354
355
    public function distinct(): ListInterface
356
    {
357
        return listOf(...array_unique($this->array));
358
    }
359
360 4
    public function forEach(callable $action): void
361
    {
362 4
        foreach ($this->array as $element) {
363 4
            $action($element);
364
        }
365 4
    }
366
367
    /**
368
     * @inheritDoc
369
     */
370
    public function getOrElse(int $index, callable $defaultValue)
371
    {
372
        if ($this->array[$index] !== null) {
373
            return $this->array[$index];
374
        }
375
        return $defaultValue();
376
    }
377
378
    /**
379
     * @inheritDoc
380
     * @param int $fromIndex
381
     * @param int $toIndex
382
     * @return ListInterface
383
     */
384
    public function subList(int $fromIndex, int $toIndex): ListInterface
385
    {
386
        $list = emptyList();
387
        for ($i = $fromIndex; $i < $toIndex; ++$i) {
388
            if (isset($this->array[$i])) {
389
                $list->add($this->array[$i]);
390
            }
391
        }
392
        return $list;
393
    }
394
395
396
397
    /**
398
     * Return first element of this list that matches the matchingCondition
399
     *
400
     * @param callable $matchingCondition
401
     * @return mixed|null
402
     */
403
    public function searchBy(callable $matchingCondition)
404
    {
405
        $list = listOf(...array_filter($this->array));
406
        return $list->filter($matchingCondition)->first();
407
    }
408
409 1
    public function isEmpty(): bool
410
    {
411 1
        return $this->count() === 0;
412
    }
413
}
414