Passed
Push — master ( 4dbffe...ca96a4 )
by Sebastian
57s queued 16s
created

ArrayListTrait::contains()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

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