Passed
Push — version-4 ( a11473...195886 )
by Sebastian
02:10
created

ArrayListTrait::contains()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 14
ccs 7
cts 7
cp 1
crap 3
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\Comparable\Comparable;
15
use Seboettg\Collection\Lists\ListFeatures\ListAccessTrait;
16
use Seboettg\Collection\Lists\ListFeatures\ListOperationsTrait;
17
use Seboettg\Collection\Lists\MapFeatures\MapFeaturesTrait;
18
use Seboettg\Collection\NativePhp\IteratorTrait;
19
use function Seboettg\Collection\Assert\assertComparable;
20
use function Seboettg\Collection\Assert\assertStringable;
21
22
/**
23
 * @property array $array Base array of this data structure
24
 */
25
trait ArrayListTrait
26
{
27
    use ListAccessTrait,
28
        IteratorTrait,
29
        ListOperationsTrait,
30
        MapFeaturesTrait;
31
32
    /**
33
     * flush array list
34
     *
35
     * @return ListInterface|ArrayListTrait
36
     */
37 1
    public function clear(): void
38
    {
39 1
        unset($this->array);
40 1
        $this->array = [];
41 1
    }
42
43
    /**
44
     * Adds the specified element to the end of this list.
45
     *
46
     * @param mixed $element
47
     */
48 25
    public function add($element): void
49
    {
50 25
        end($this->array);
51 25
        $this->array[] = $element;
52 25
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57 3
    public function addAll(iterable $elements): void
58
    {
59 3
        foreach ($elements as $element) {
60 3
            $this->add($element);
61
        }
62 3
    }
63
64
    /**
65
     * @inheritDoc
66
     */
67 1
    public function remove($key): void
68
    {
69 1
        unset($this->array[$key]);
70 1
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75 9
    public function contains($value): bool
76
    {
77
        if (
78 9
            isScalarOrStringable($value) /* && $this->all(fn($item) => isScalarOrStringable($item)))*/ ||
79 9
            isComparable($value)
80
        ) {
81
            // use custom in_array function
82 8
            return in_array($value, $this->array) !== false;
83
        }
84
        else {
85
            // use PHP's native \in_array function
86 1
            return \in_array(
87 1
                print_r($value, true),
88 1
                array_map(fn($item): string => print_r($item, true), $this->array)
89
            );
90
        }
91
    }
92
93
    /**
94
     * @inheritDoc
95
     */
96 1
    public function shuffle(): ListInterface
97
    {
98 1
        $array = $this->array;
99 1
        shuffle($array);
100 1
        return listFromArray($array);
101
    }
102
103
    /**
104
     * @inheritDoc
105
     */
106 12
    public function filter(?callable $predicate = null, bool $preserveKeys = false): ListInterface
107
    {
108 12
        $list = emptyList();
109 12
        $filtered = $predicate == null ? array_filter($this->array) : array_filter($this->array, $predicate);
110 12
        $list->setArray(
111 12
            $preserveKeys ? $filtered : array_values($filtered)
112
        );
113 12
        return $list;
114
    }
115
116
    /**
117
     * @param array $array
118
     */
119 56
    public function setArray(array $array): void
120
    {
121 56
        $this->replace($array);
122 56
    }
123
124
    /**
125
     * @param array $data
126
     */
127 56
    public function replace(array $data): void
128
    {
129 56
        $this->array = $data;
130 56
    }
131
132
    /**
133
     * returns a new ArrayList containing all the elements of this ArrayList after applying the callback function to each one.
134
     * @param callable $mapFunction
135
     * @return ListInterface|ArrayListTrait
136
     */
137 7
    public function map(callable $mapFunction): ListInterface
138
    {
139 7
        $list = emptyList();
140 7
        foreach ($this as $value) {
141 7
            $list->add($mapFunction($value));
142
        }
143 6
        return $list;
144
    }
145
146
    /**
147
     * @inheritDoc
148
     * @param callable $mapFunction
149
     * @return ListInterface
150
     */
151 1
    public function mapNotNull(callable $mapFunction): ListInterface
152
    {
153 1
        $list = $this->map($mapFunction);
154 1
        return $list->filter();
155
    }
156
157
    /**
158
     * Returns a new ArrayList containing a one-dimensional array of all elements of this ArrayList. Keys are going lost.
159
     * @return ListInterface
160
     */
161 1
    public function flatten(): ListInterface
162
    {
163 1
        $flattenedArray = [];
164
        array_walk_recursive($this->array, function ($item) use (&$flattenedArray) {
165 1
            $flattenedArray[] = $item;
166 1
        });
167 1
        return listOf(...$flattenedArray);
168
    }
169
170
    /**
171
     * @inheritDoc
172
     * @param callable $collectFunction
173
     * @return mixed
174
     */
175 1
    public function collect(callable $collectFunction)
176
    {
177 1
        return $collectFunction($this->array);
178
    }
179
180
    /**
181
     * @inheritDoc
182
     */
183 4
    public function joinToString(string $delimiter, string $prefix = null, string $suffix = null): string
184
    {
185
        $result = implode($delimiter, $this->map(function ($item) {
186 4
            assertStringable(
187 4
                $item,
188 4
                "All elements in the list must be convertible to string in order to use joinToString."
189
            );
190 3
            return strval($item);
191 4
        })->toArray());
192 3
        if ($prefix !== null) {
193
            $result = $prefix . $result;
194
        }
195 3
        if ($suffix !== null) {
196
            $result = $result . $suffix;
197
        }
198 3
        return $result;
199
    }
200
201
    /**
202
     * @inheritDoc
203
     * @deprecated use joinToString instead
204
     */
205 1
    public function collectToString(string $delimiter): string
206
    {
207 1
        return $this->joinToString($delimiter);
208
    }
209
210
    /**
211
     * @inheritDoc
212
     * @return int
213
     */
214 19
    public function count(): int
215
    {
216 19
        return count($this->array);
217
    }
218
219
    /**
220
     * @inheritDoc
221
     */
222 1
    public function size(): int
223
    {
224 1
        return $this->count();
225
    }
226
227 2
    public function any(callable $predicate): bool
228
    {
229 2
        return $this->filter($predicate)->count() > 0;
230
    }
231
232 3
    public function all(callable $predicate): bool
233
    {
234 3
        return $this->count() === $this->filter($predicate)->count();
235
    }
236
237
    /**
238
     * @inheritDoc
239
     */
240 2
    public function chunk(int $size): ListInterface
241
    {
242 2
        $listOfChunks = emptyList();
243 2
        $arrayChunks = array_chunk($this->array, $size);
244 2
        foreach ($arrayChunks as $arrayChunk) {
245 2
            $listOfChunks->add(listOf(...$arrayChunk));
246
        }
247 2
        return $listOfChunks;
248
    }
249
250 1
    public function distinct(): ListInterface
251
    {
252 1
        $this->forEach(fn($item) => assertComparable($item,
253 1
            sprintf(
254 1
                "Each item must be of type scalar or implement \Stringable or implement %s",
255 1
                Comparable::class
256
            )
257 1
        ));
258 1
        $newList = emptyList();
259 1
        if ($this->all(fn($item): bool => isScalarOrStringable($item))) {
260
            return listFromArray(array_unique($this->toArray()));
261
        } else {
262 1
            if ($this->all(fn($item): bool => isComparable($item))) {
263 1
                $values = $this->array;
264 1
                foreach ($values as $value) {
265 1
                    if (!$newList->contains($value)) {
266 1
                        $newList->add($value);
267
                    }
268
                }
269 1
                return $newList;
270
            }
271
        }
272
        return listFromArray($this->array);
273
    }
274
275
    /**
276
     * @inheritDoc
277
     */
278 8
    public function forEach(callable $action): void
279
    {
280 8
        foreach ($this->array as $element) {
281 8
            $action($element);
282
        }
283 8
    }
284
285
    /**
286
     * @inheritDoc
287
     */
288 2
    public function getOrElse(int $index, callable $defaultValue)
289
    {
290 2
        if (array_key_exists($index, $this->array)) {
291 1
            return $this->array[$index];
292
        }
293 1
        return $defaultValue($this);
294
    }
295
296
    /**
297
     * @inheritDoc
298
     * @param int $fromIndex
299
     * @param int $toIndex
300
     * @return ListInterface
301
     */
302 1
    public function subList(int $fromIndex, int $toIndex): ListInterface
303
    {
304 1
        $list = emptyList();
305 1
        for ($i = $fromIndex; $i < $toIndex; ++$i) {
306 1
            if (isset($this->array[$i])) {
307 1
                $list->add($this->array[$i]);
308
            }
309
        }
310 1
        return $list;
311
    }
312
313
    /**
314
     * Return first element of this list that matches the matchingCondition. If no element matches the condition, null
315
     * will be returned.
316
     *
317
     * @param callable $matchingCondition
318
     * @return mixed|null
319
     */
320 2
    public function searchBy(callable $matchingCondition)
321
    {
322 2
        $list = listOf(...array_filter($this->array));
323
        return $list
324 2
            ->filter($matchingCondition)
325 2
            ->getOrElse(0, fn() => null);
326
    }
327
328 2
    public function isEmpty(): bool
329
    {
330 2
        return $this->count() === 0;
331
    }
332
333
    /**
334
     * {@inheritDoc}
335
     */
336 9
    public function toArray(): array
337
    {
338 9
        return $this->array;
339
    }
340
}
341