These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Arrayy; |
||
6 | |||
7 | use voku\helper\UTF8; |
||
8 | |||
9 | /** @noinspection ClassReImplementsParentInterfaceInspection */ |
||
10 | |||
11 | /** |
||
12 | * Methods to manage arrays. |
||
13 | * |
||
14 | * For the full copyright and license information, please view the LICENSE |
||
15 | * file that was distributed with this source code. |
||
16 | */ |
||
17 | class Arrayy extends \ArrayObject implements \IteratorAggregate, \ArrayAccess, \Serializable, \Countable |
||
18 | { |
||
19 | /** |
||
20 | * @var array |
||
21 | */ |
||
22 | protected $array = []; |
||
23 | |||
24 | /** |
||
25 | * @var string |
||
26 | */ |
||
27 | protected $iteratorClass = ArrayyIterator::class; |
||
28 | |||
29 | /** |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $pathSeparator = '.'; |
||
33 | |||
34 | /** |
||
35 | * @var bool |
||
36 | */ |
||
37 | protected $checkPropertyTypes = false; |
||
38 | |||
39 | /** |
||
40 | * @var bool |
||
41 | */ |
||
42 | protected $checkPropertiesMismatchInConstructor = false; |
||
43 | |||
44 | /** |
||
45 | * @var array|Property[] |
||
46 | */ |
||
47 | protected $properties = []; |
||
48 | |||
49 | /** @noinspection MagicMethodsValidityInspection */ |
||
50 | /** |
||
51 | * Initializes |
||
52 | * |
||
53 | * @param mixed $array <p>Should be an array, otherwise it will try to convert it into an array.</p> |
||
54 | * @param string $iteratorClass |
||
55 | */ |
||
56 | 888 | public function __construct($array = [], $iteratorClass = ArrayyIterator::class) |
|
57 | { |
||
58 | 888 | $array = $this->fallbackForArray($array); |
|
59 | |||
60 | if ( |
||
61 | 886 | $this->checkPropertyTypes === true |
|
62 | || |
||
63 | 886 | $this->checkForMissingPropertiesInConstructor === true |
|
0 ignored issues
–
show
|
|||
64 | ) { |
||
65 | 8 | $this->properties = $this->getPublicProperties(); |
|
66 | } |
||
67 | |||
68 | if ( |
||
69 | 886 | $this->checkPropertiesMismatchInConstructor === true |
|
70 | && |
||
71 | 886 | \count($array) !== 0 |
|
72 | && |
||
73 | 886 | \count(\array_diff_key($this->properties, $array)) > 0 |
|
74 | ) { |
||
75 | 1 | throw new \InvalidArgumentException('Property mismatch - input: ' . print_r(array_keys($array), true) . ' | expected: ' . print_r(array_keys($this->properties), true)); |
|
76 | } |
||
77 | |||
78 | 885 | foreach ($array as $key => $value) { |
|
79 | 773 | $this->internalSet($key, $value); |
|
80 | } |
||
81 | |||
82 | 883 | $this->setIteratorClass($iteratorClass); |
|
83 | 883 | } |
|
84 | |||
85 | /** |
||
86 | * Get a value by key. |
||
87 | * |
||
88 | * @param mixed $key |
||
89 | * |
||
90 | * @return mixed <p>Get a Value from the current array.</p> |
||
91 | */ |
||
92 | 879 | public function &__get($key) |
|
93 | { |
||
94 | 879 | $return = $this->get($key); |
|
95 | |||
96 | 879 | if (\is_array($return)) { |
|
97 | return static::create($return); |
||
98 | } |
||
99 | |||
100 | 879 | return $return; |
|
101 | } |
||
102 | |||
103 | /** |
||
104 | * Call object as function. |
||
105 | * |
||
106 | * @param mixed $key |
||
107 | * |
||
108 | * @return mixed |
||
109 | */ |
||
110 | 1 | public function __invoke($key = null) |
|
111 | { |
||
112 | 1 | if ($key !== null) { |
|
113 | 1 | if (isset($this->array[$key])) { |
|
114 | 1 | return $this->array[$key]; |
|
115 | } |
||
116 | |||
117 | return false; |
||
118 | } |
||
119 | |||
120 | return (array)$this->array; |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * Whether or not an element exists by key. |
||
125 | * |
||
126 | * @param mixed $key |
||
127 | * |
||
128 | * @return bool <p>True is the key/index exists, otherwise false.</p> |
||
129 | */ |
||
130 | public function __isset($key) |
||
131 | { |
||
132 | return $this->offsetExists($key); |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * Assigns a value to the specified element. |
||
137 | * |
||
138 | * @param mixed $key |
||
139 | * @param mixed $value |
||
140 | */ |
||
141 | 2 | public function __set($key, $value) |
|
142 | { |
||
143 | 2 | $this->internalSet($key, $value); |
|
144 | 2 | } |
|
145 | |||
146 | /** |
||
147 | * magic to string |
||
148 | * |
||
149 | * @return string |
||
150 | */ |
||
151 | 15 | public function __toString() |
|
152 | { |
||
153 | 15 | return $this->toString(); |
|
154 | } |
||
155 | |||
156 | /** |
||
157 | * Unset element by key. |
||
158 | * |
||
159 | * @param mixed $key |
||
160 | */ |
||
161 | public function __unset($key) |
||
162 | { |
||
163 | $this->internalRemove($key); |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * alias: for "Arrayy->append()" |
||
168 | * |
||
169 | * @see Arrayy::append() |
||
170 | * |
||
171 | * @param mixed $value |
||
172 | * |
||
173 | * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p> |
||
174 | */ |
||
175 | 1 | public function add($value) |
|
176 | { |
||
177 | 1 | return $this->append($value); |
|
178 | } |
||
179 | |||
180 | /** |
||
181 | * Append a (key) + value to the current array. |
||
182 | * |
||
183 | * @param mixed $value |
||
184 | * @param mixed $key |
||
185 | * |
||
186 | * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p> |
||
187 | */ |
||
188 | 9 | public function append($value, $key = null) |
|
189 | { |
||
190 | 9 | if ($key !== null) { |
|
191 | if ( |
||
192 | isset($this->array[$key]) |
||
193 | && |
||
194 | \is_array($this->array[$key]) |
||
195 | ) { |
||
196 | $this->array[$key][] = $value; |
||
197 | } else { |
||
198 | $this->array[$key] = $value; |
||
199 | } |
||
200 | } else { |
||
201 | 9 | $this->array[] = $value; |
|
202 | } |
||
203 | |||
204 | 9 | return $this; |
|
205 | } |
||
206 | |||
207 | /** |
||
208 | * Sort the entries by value. |
||
209 | * |
||
210 | * @param int $sort_flags [optional] <p> |
||
211 | * You may modify the behavior of the sort using the optional |
||
212 | * parameter sort_flags, for details |
||
213 | * see sort. |
||
214 | * </p> |
||
215 | * |
||
216 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
217 | */ |
||
218 | 4 | public function asort(int $sort_flags = 0) |
|
219 | { |
||
220 | 4 | \asort($this->array, $sort_flags); |
|
221 | |||
222 | 4 | return $this; |
|
223 | } |
||
224 | |||
225 | /** |
||
226 | * Counts all elements in an array, or something in an object. |
||
227 | * <p>For objects, if you have SPL installed, you can hook into count() by implementing interface {@see Countable}. |
||
228 | * The interface has exactly one method, {@see Countable::count()}, which returns the return value for the count() |
||
229 | * function. Please see the {@see Array} section of the manual for a detailed explanation of how arrays are |
||
230 | * implemented and used in PHP. |
||
231 | * |
||
232 | * @link http://php.net/manual/en/function.count.php |
||
233 | * |
||
234 | * @param int $mode [optional] If the optional mode parameter is set to |
||
235 | * COUNT_RECURSIVE (or 1), count |
||
236 | * will recursively count the array. This is particularly useful for |
||
237 | * counting all the elements of a multidimensional array. count does not detect infinite recursion. |
||
238 | * |
||
239 | * @return int the number of elements in var, which is |
||
240 | * typically an array, since anything else will have one |
||
241 | * element. |
||
242 | * </p> |
||
243 | * <p> |
||
244 | * If var is not an array or an object with |
||
245 | * implemented Countable interface, |
||
246 | * 1 will be returned. |
||
247 | * There is one exception, if var is &null;, |
||
248 | * 0 will be returned. |
||
249 | * </p> |
||
250 | * <p> |
||
251 | * Caution: count may return 0 for a variable that isn't set, |
||
252 | * but it may also return 0 for a variable that has been initialized with an |
||
253 | * empty array. Use isset to test if a variable is set. |
||
254 | * |
||
255 | * @return int |
||
256 | */ |
||
257 | 37 | public function count(int $mode = COUNT_NORMAL): int |
|
258 | { |
||
259 | 37 | return \count($this->array, $mode); |
|
260 | } |
||
261 | |||
262 | /** |
||
263 | * Exchange the array for another one. |
||
264 | * |
||
265 | * @param array|static $data |
||
266 | * |
||
267 | * @return array |
||
268 | */ |
||
269 | 1 | public function exchangeArray($data): array |
|
270 | { |
||
271 | 1 | $this->array = $this->fallbackForArray($data); |
|
272 | |||
273 | 1 | return $this->array; |
|
274 | } |
||
275 | |||
276 | /** |
||
277 | * Creates a copy of the ArrayyObject. |
||
278 | * |
||
279 | * @return array |
||
280 | */ |
||
281 | 1 | public function getArrayCopy(): array |
|
282 | { |
||
283 | 1 | return $this->array; |
|
284 | } |
||
285 | |||
286 | /** |
||
287 | * Returns a new ArrayyIterator, thus implementing the \ArrayIterator interface. |
||
288 | * |
||
289 | * @return \ArrayIterator <p>An iterator for the values in the array.</p> |
||
290 | */ |
||
291 | 12 | public function getIterator(): \ArrayIterator |
|
292 | { |
||
293 | 12 | $iterator = $this->getIteratorClass(); |
|
294 | |||
295 | 12 | return new $iterator($this->array); |
|
296 | } |
||
297 | |||
298 | /** |
||
299 | * Gets the iterator classname for the ArrayObject. |
||
300 | * |
||
301 | * @return string |
||
302 | */ |
||
303 | 12 | public function getIteratorClass(): string |
|
304 | { |
||
305 | 12 | return $this->iteratorClass; |
|
306 | } |
||
307 | |||
308 | /** |
||
309 | * Sort the entries by key |
||
310 | * |
||
311 | * @param int $sort_flags [optional] <p> |
||
312 | * You may modify the behavior of the sort using the optional |
||
313 | * parameter sort_flags, for details |
||
314 | * see sort. |
||
315 | * </p> |
||
316 | * |
||
317 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
318 | */ |
||
319 | 4 | public function ksort(int $sort_flags = 0) |
|
320 | { |
||
321 | 4 | \ksort($this->array, $sort_flags); |
|
322 | |||
323 | 4 | return $this; |
|
324 | } |
||
325 | |||
326 | /** |
||
327 | * Sort an array using a case insensitive "natural order" algorithm |
||
328 | * |
||
329 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
330 | */ |
||
331 | public function natcasesort() |
||
332 | { |
||
333 | \natcasesort($this->array); |
||
334 | |||
335 | return $this; |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * Sort entries using a "natural order" algorithm |
||
340 | * |
||
341 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
342 | */ |
||
343 | 1 | public function natsort() |
|
344 | { |
||
345 | 1 | \natsort($this->array); |
|
346 | |||
347 | 1 | return $this; |
|
348 | } |
||
349 | |||
350 | /** |
||
351 | * Whether or not an offset exists. |
||
352 | * |
||
353 | * @param int|float|string $offset |
||
354 | * |
||
355 | * @return bool |
||
356 | */ |
||
357 | 44 | public function offsetExists($offset): bool |
|
358 | { |
||
359 | 44 | if ($this->isEmpty()) { |
|
360 | 4 | return false; |
|
361 | } |
||
362 | |||
363 | // php cast "bool"-index into "int"-index |
||
364 | 40 | if ((bool)$offset === $offset) { |
|
365 | 1 | $offset = (int)$offset; |
|
366 | } |
||
367 | |||
368 | 40 | $tmpReturn = \array_key_exists($offset, $this->array); |
|
369 | |||
370 | if ( |
||
371 | 40 | $tmpReturn === true |
|
372 | || |
||
373 | ( |
||
374 | 16 | $tmpReturn === false |
|
375 | && |
||
376 | 40 | \strpos((string)$offset, $this->pathSeparator) === false |
|
377 | ) |
||
378 | ) { |
||
379 | 38 | return $tmpReturn; |
|
380 | } |
||
381 | |||
382 | 3 | $offsetExists = false; |
|
383 | |||
384 | 3 | if (\strpos((string)$offset, $this->pathSeparator) !== false) { |
|
385 | |||
386 | 3 | $offsetExists = false; |
|
387 | 3 | $explodedPath = \explode($this->pathSeparator, (string)$offset); |
|
388 | 3 | $lastOffset = \array_pop($explodedPath); |
|
389 | 3 | $containerPath = \implode($this->pathSeparator, $explodedPath); |
|
390 | |||
391 | 3 | $this->callAtPath( |
|
392 | 3 | $containerPath, |
|
393 | 3 | function ($container) use ($lastOffset, &$offsetExists) { |
|
0 ignored issues
–
show
function ($container) us...tOffset, $container); } is of type object<Closure> , but the function expects a object<callable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
394 | 3 | $offsetExists = \array_key_exists($lastOffset, $container); |
|
395 | 3 | } |
|
396 | ); |
||
397 | } |
||
398 | |||
399 | 3 | return $offsetExists; |
|
400 | } |
||
401 | |||
402 | /** |
||
403 | * Returns the value at specified offset. |
||
404 | * |
||
405 | * @param int|float|string $offset |
||
406 | * |
||
407 | * @return mixed <p>Will return null if the offset did not exists.</p> |
||
408 | */ |
||
409 | 30 | public function offsetGet($offset) |
|
410 | { |
||
411 | 30 | return $this->offsetExists($offset) ? $this->get($offset) : null; |
|
412 | } |
||
413 | |||
414 | /** |
||
415 | * Assigns a value to the specified offset. |
||
416 | * |
||
417 | * @param null|int|string $offset |
||
418 | * @param mixed $value |
||
419 | */ |
||
420 | 20 | public function offsetSet($offset, $value) |
|
421 | { |
||
422 | 20 | if ($offset === null) { |
|
423 | 4 | $this->array[] = $value; |
|
424 | } else { |
||
425 | 16 | $this->internalSet($offset, $value); |
|
426 | } |
||
427 | 20 | } |
|
428 | |||
429 | /** |
||
430 | * Unset an offset. |
||
431 | * |
||
432 | * @param int|float|string $offset |
||
433 | */ |
||
434 | 7 | public function offsetUnset($offset) |
|
435 | { |
||
436 | 7 | if ($this->isEmpty()) { |
|
437 | 1 | return; |
|
438 | } |
||
439 | |||
440 | 6 | if (\array_key_exists($offset, $this->array)) { |
|
441 | 4 | unset($this->array[$offset]); |
|
442 | |||
443 | 4 | return; |
|
444 | } |
||
445 | |||
446 | 3 | if (\strpos((string)$offset, $this->pathSeparator) !== false) { |
|
447 | |||
448 | 2 | $path = \explode($this->pathSeparator, (string)$offset); |
|
449 | 2 | $pathToUnset = \array_pop($path); |
|
450 | |||
451 | 2 | $this->callAtPath( |
|
452 | 2 | \implode($this->pathSeparator, $path), |
|
453 | 2 | function (&$offset) use ($pathToUnset) { |
|
0 ignored issues
–
show
function (&$offset) use(...ffset[$pathToUnset]); } is of type object<Closure> , but the function expects a object<callable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
454 | 2 | unset($offset[$pathToUnset]); |
|
455 | 2 | } |
|
456 | ); |
||
457 | |||
458 | } |
||
459 | 3 | } |
|
460 | |||
461 | /** @noinspection SenselessProxyMethodInspection | can not add return type, because of the "Serializable" interface */ |
||
462 | /** |
||
463 | * Serialize the current "Arrayy"-object. |
||
464 | * |
||
465 | * @return string |
||
466 | */ |
||
467 | 1 | public function serialize() |
|
468 | { |
||
469 | 1 | return parent::serialize(); |
|
470 | } |
||
471 | |||
472 | /** |
||
473 | * Sets the iterator classname for the current "Arrayy"-object. |
||
474 | * |
||
475 | * @param string $class |
||
476 | * |
||
477 | * @return void |
||
478 | * |
||
479 | * @throws \InvalidArgumentException |
||
480 | */ |
||
481 | 883 | public function setIteratorClass($class) |
|
482 | { |
||
483 | 883 | if (\class_exists($class)) { |
|
484 | 883 | $this->iteratorClass = $class; |
|
485 | |||
486 | 883 | return; |
|
487 | } |
||
488 | |||
489 | if (\strpos($class, '\\') === 0) { |
||
490 | $class = '\\' . $class; |
||
491 | if (\class_exists($class)) { |
||
492 | $this->iteratorClass = $class; |
||
493 | |||
494 | return; |
||
495 | } |
||
496 | } |
||
497 | |||
498 | throw new \InvalidArgumentException('The iterator class does not exist: ' . $class); |
||
499 | } |
||
500 | |||
501 | /** |
||
502 | * Sort the entries with a user-defined comparison function and maintain key association. |
||
503 | * |
||
504 | * @param \callable $function |
||
505 | * |
||
506 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
507 | * |
||
508 | * @throws \InvalidArgumentException |
||
509 | */ |
||
510 | View Code Duplication | public function uasort($function) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
511 | { |
||
512 | if (!\is_callable($function)) { |
||
513 | throw new \InvalidArgumentException( |
||
514 | 'Passed function must be callable' |
||
515 | ); |
||
516 | } |
||
517 | |||
518 | \uasort($this->array, $function); |
||
519 | |||
520 | return $this; |
||
521 | } |
||
522 | |||
523 | /** |
||
524 | * Sort the entries by keys using a user-defined comparison function. |
||
525 | * |
||
526 | * @param \callable $function |
||
527 | * |
||
528 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
529 | * |
||
530 | * @throws \InvalidArgumentException |
||
531 | */ |
||
532 | 5 | public function uksort($function) |
|
533 | { |
||
534 | 5 | return $this->customSortKeys($function); |
|
535 | } |
||
536 | |||
537 | /** |
||
538 | * Unserialize an string and return this object. |
||
539 | * |
||
540 | * @param string $string |
||
541 | * |
||
542 | * @return static <p>(Mutable)</p> |
||
543 | */ |
||
544 | 1 | public function unserialize($string) |
|
545 | { |
||
546 | 1 | parent::unserialize($string); |
|
547 | |||
548 | 1 | return $this; |
|
549 | } |
||
550 | |||
551 | /** |
||
552 | * Append a (key) + values to the current array. |
||
553 | * |
||
554 | * @param array $values |
||
555 | * @param mixed $key |
||
556 | * |
||
557 | * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p> |
||
558 | */ |
||
559 | 1 | public function appendArrayValues(array $values, $key = null) |
|
560 | { |
||
561 | 1 | if ($key !== null) { |
|
562 | if ( |
||
563 | 1 | isset($this->array[$key]) |
|
564 | && |
||
565 | 1 | \is_array($this->array[$key]) |
|
566 | ) { |
||
567 | 1 | foreach ($values as $value) { |
|
568 | 1 | $this->array[$key][] = $value; |
|
569 | } |
||
570 | } else { |
||
571 | foreach ($values as $value) { |
||
572 | 1 | $this->array[$key] = $value; |
|
573 | } |
||
574 | } |
||
575 | } else { |
||
576 | foreach ($values as $value) { |
||
577 | $this->array[] = $value; |
||
578 | } |
||
579 | } |
||
580 | |||
581 | 1 | return $this; |
|
582 | } |
||
583 | |||
584 | /** |
||
585 | * Add a suffix to each key. |
||
586 | * |
||
587 | * @param mixed $prefix |
||
588 | * |
||
589 | * @return static <p>(Immutable) Return an Arrayy object, with the prefixed keys.</p> |
||
590 | */ |
||
591 | 10 | View Code Duplication | public function appendToEachKey($prefix) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
592 | { |
||
593 | // init |
||
594 | 10 | $result = []; |
|
595 | |||
596 | 10 | foreach ($this->getGenerator() as $key => $item) { |
|
597 | 9 | if ($item instanceof self) { |
|
598 | $result[$prefix . $key] = $item->appendToEachKey($prefix); |
||
599 | 9 | } elseif (\is_array($item)) { |
|
600 | $result[$prefix . $key] = self::create($item)->appendToEachKey($prefix)->toArray(); |
||
601 | } else { |
||
602 | 9 | $result[$prefix . $key] = $item; |
|
603 | } |
||
604 | } |
||
605 | |||
606 | 10 | return self::create($result); |
|
607 | } |
||
608 | |||
609 | /** |
||
610 | * Add a prefix to each value. |
||
611 | * |
||
612 | * @param mixed $prefix |
||
613 | * |
||
614 | * @return static <p>(Immutable) Return an Arrayy object, with the prefixed values.</p> |
||
615 | */ |
||
616 | 10 | View Code Duplication | public function appendToEachValue($prefix) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
617 | { |
||
618 | // init |
||
619 | 10 | $result = []; |
|
620 | |||
621 | 10 | foreach ($this->getGenerator() as $key => $item) { |
|
622 | 9 | if ($item instanceof self) { |
|
623 | $result[$key] = $item->appendToEachValue($prefix); |
||
624 | 9 | } elseif (\is_array($item)) { |
|
625 | $result[$key] = self::create($item)->appendToEachValue($prefix)->toArray(); |
||
626 | 9 | } elseif (\is_object($item)) { |
|
627 | 1 | $result[$key] = $item; |
|
628 | } else { |
||
629 | 9 | $result[$key] = $prefix . $item; |
|
630 | } |
||
631 | } |
||
632 | |||
633 | 10 | return self::create($result); |
|
634 | } |
||
635 | |||
636 | /** |
||
637 | * Convert an array into a object. |
||
638 | * |
||
639 | * @param array $array PHP array |
||
640 | * |
||
641 | * @return \stdClass (object) |
||
642 | */ |
||
643 | 4 | protected static function arrayToObject(array $array = []): \stdClass |
|
644 | { |
||
645 | // init |
||
646 | 4 | $object = new \stdClass(); |
|
647 | |||
648 | 4 | if (\count($array, COUNT_NORMAL) <= 0) { |
|
649 | 1 | return $object; |
|
650 | } |
||
651 | |||
652 | 3 | foreach ($array as $name => $value) { |
|
653 | 3 | if (\is_array($value)) { |
|
654 | 1 | $object->{$name} = self::arrayToObject($value); |
|
655 | } else { |
||
656 | 3 | $object->{$name} = $value; |
|
657 | } |
||
658 | } |
||
659 | |||
660 | 3 | return $object; |
|
661 | } |
||
662 | |||
663 | /** |
||
664 | * @param array $input <p> |
||
665 | * An array containing keys to return. |
||
666 | * </p> |
||
667 | * @param mixed $search_value [optional] <p> |
||
668 | * If specified, then only keys containing these values are returned. |
||
669 | * </p> |
||
670 | * @param bool $strict [optional] <p> |
||
671 | * Determines if strict comparison (===) should be used during the search. |
||
672 | * </p> |
||
673 | * |
||
674 | * @return array an array of all the keys in input. |
||
675 | */ |
||
676 | 10 | protected function array_keys_recursive(array $input = null, $search_value = null, bool $strict = true): array |
|
677 | { |
||
678 | // init |
||
679 | 10 | $keys = []; |
|
680 | 10 | $keysTmp = [[]]; // the inner empty array covers cases when no loops were made |
|
681 | |||
682 | 10 | if ($input === null) { |
|
683 | $input = $this->getGenerator(); |
||
684 | } |
||
685 | |||
686 | 10 | foreach ($input as $key => $value) { |
|
687 | |||
688 | if ( |
||
689 | 10 | $search_value === null |
|
690 | || |
||
691 | ( |
||
692 | \is_array($search_value) === true |
||
693 | && |
||
694 | 10 | \in_array($key, $search_value, $strict) |
|
695 | ) |
||
696 | ) { |
||
697 | 10 | $keys[] = $key; |
|
698 | } |
||
699 | |||
700 | // check if recursive is needed |
||
701 | 10 | if (\is_array($value) === true) { |
|
702 | 10 | $keysTmp[] = $this->array_keys_recursive($value); |
|
703 | } |
||
704 | } |
||
705 | |||
706 | 10 | $keys = \array_merge($keys, ...$keysTmp); |
|
707 | |||
708 | 10 | return $keys; |
|
709 | } |
||
710 | |||
711 | /** |
||
712 | * Sort an array in reverse order and maintain index association. |
||
713 | * |
||
714 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
715 | */ |
||
716 | 4 | public function arsort() |
|
717 | { |
||
718 | 4 | \arsort($this->array); |
|
719 | |||
720 | 4 | return $this; |
|
721 | } |
||
722 | |||
723 | /** |
||
724 | * Iterate over the current array and execute a callback for each loop. |
||
725 | * |
||
726 | * @param \Closure $closure |
||
727 | * |
||
728 | * @return static <p>(Immutable)</p> |
||
729 | */ |
||
730 | 2 | public function at(\Closure $closure) |
|
731 | { |
||
732 | 2 | $arrayy = clone $this; |
|
733 | |||
734 | 2 | foreach ($arrayy->getGenerator() as $key => $value) { |
|
735 | 2 | $closure($value, $key); |
|
736 | } |
||
737 | |||
738 | 2 | return static::create($arrayy->toArray()); |
|
739 | } |
||
740 | |||
741 | /** |
||
742 | * Returns the average value of the current array. |
||
743 | * |
||
744 | * @param int $decimals <p>The number of decimal-numbers to return.</p> |
||
745 | * |
||
746 | * @return int|double <p>The average value.</p> |
||
747 | */ |
||
748 | 10 | public function average($decimals = 0) |
|
749 | { |
||
750 | 10 | $count = \count($this->array, COUNT_NORMAL); |
|
751 | |||
752 | 10 | if (!$count) { |
|
753 | 2 | return 0; |
|
754 | } |
||
755 | |||
756 | 8 | if (!\is_int($decimals)) { |
|
757 | 3 | $decimals = 0; |
|
758 | } |
||
759 | |||
760 | 8 | return \round(\array_sum($this->array) / $count, $decimals); |
|
761 | } |
||
762 | |||
763 | /** |
||
764 | * @param mixed $path |
||
765 | * @param \callable $callable |
||
766 | * @param null|array $currentOffset |
||
767 | */ |
||
768 | 4 | protected function callAtPath($path, $callable, &$currentOffset = null) |
|
769 | { |
||
770 | 4 | if ($currentOffset === null) { |
|
771 | 4 | $currentOffset = &$this->array; |
|
772 | } |
||
773 | |||
774 | 4 | $explodedPath = \explode($this->pathSeparator, $path); |
|
775 | 4 | $nextPath = \array_shift($explodedPath); |
|
776 | |||
777 | 4 | if (!isset($currentOffset[$nextPath])) { |
|
778 | return; |
||
779 | } |
||
780 | |||
781 | 4 | if (!empty($explodedPath)) { |
|
782 | 1 | $this->callAtPath( |
|
783 | 1 | \implode($this->pathSeparator, $explodedPath), |
|
784 | 1 | $callable, |
|
785 | 1 | $currentOffset[$nextPath] |
|
786 | ); |
||
787 | } else { |
||
788 | 4 | $callable($currentOffset[$nextPath]); |
|
789 | } |
||
790 | 4 | } |
|
791 | |||
792 | /** |
||
793 | * Changes all keys in an array. |
||
794 | * |
||
795 | * @param int $case [optional] <p> Either <strong>CASE_UPPER</strong><br /> |
||
796 | * or <strong>CASE_LOWER</strong> (default)</p> |
||
797 | * |
||
798 | * @return static <p>(Immutable)</p> |
||
799 | */ |
||
800 | 1 | public function changeKeyCase(int $case = CASE_LOWER) |
|
801 | { |
||
802 | 1 | return static::create(UTF8::array_change_key_case($this->array, $case)); |
|
803 | } |
||
804 | |||
805 | /** |
||
806 | * Change the path separator of the array wrapper. |
||
807 | * |
||
808 | * By default, the separator is: "." |
||
809 | * |
||
810 | * @param string $separator <p>Separator to set.</p> |
||
811 | * |
||
812 | * @return static <p>Mutable</p> |
||
813 | */ |
||
814 | 1 | public function changeSeparator($separator) |
|
815 | { |
||
816 | 1 | $this->pathSeparator = $separator; |
|
817 | |||
818 | 1 | return $this; |
|
819 | } |
||
820 | |||
821 | /** |
||
822 | * Create a chunked version of the current array. |
||
823 | * |
||
824 | * @param int $size <p>Size of each chunk.</p> |
||
825 | * @param bool $preserveKeys <p>Whether array keys are preserved or no.</p> |
||
826 | * |
||
827 | * @return static <p>(Immutable) A new array of chunks from the original array.</p> |
||
828 | */ |
||
829 | 4 | public function chunk($size, $preserveKeys = false) |
|
830 | { |
||
831 | 4 | $result = \array_chunk($this->array, $size, $preserveKeys); |
|
832 | |||
833 | 4 | return static::create($result); |
|
834 | } |
||
835 | |||
836 | /** |
||
837 | * Clean all falsy values from the current array. |
||
838 | * |
||
839 | * @return static <p>(Immutable)</p> |
||
840 | */ |
||
841 | 8 | public function clean() |
|
842 | { |
||
843 | 8 | return $this->filter( |
|
844 | 8 | function ($value) { |
|
845 | 7 | return (bool)$value; |
|
846 | 8 | } |
|
847 | ); |
||
848 | } |
||
849 | |||
850 | /** |
||
851 | * WARNING!!! -> Clear the current array. |
||
852 | * |
||
853 | * @return static <p>(Mutable) Return this Arrayy object, with an empty array.</p> |
||
854 | */ |
||
855 | 4 | public function clear() |
|
856 | { |
||
857 | 4 | $this->array = []; |
|
858 | |||
859 | 4 | return $this; |
|
860 | } |
||
861 | |||
862 | /** |
||
863 | * Check if an item is in the current array. |
||
864 | * |
||
865 | * @param string|int|float $value |
||
866 | * @param bool $recursive |
||
867 | * @param bool $strict |
||
868 | * |
||
869 | * @return bool |
||
870 | */ |
||
871 | 22 | public function contains($value, $recursive = false, $strict = true): bool |
|
872 | { |
||
873 | 22 | if ($recursive === true) { |
|
874 | 18 | return $this->in_array_recursive($value, $this->array, $strict); |
|
875 | } |
||
876 | |||
877 | 13 | return \in_array($value, $this->array, $strict); |
|
878 | } |
||
879 | |||
880 | /** |
||
881 | * Check if an (case-insensitive) string is in the current array. |
||
882 | * |
||
883 | * @param string $value |
||
884 | * @param bool $recursive |
||
885 | * |
||
886 | * @return bool |
||
887 | */ |
||
888 | 26 | public function containsCaseInsensitive($value, $recursive = false): bool |
|
889 | { |
||
890 | 26 | if ($recursive === true) { |
|
891 | 26 | return $this->in_array_recursive( |
|
892 | 26 | UTF8::strtoupper($value), |
|
893 | 26 | $this->walk( |
|
894 | 26 | function (&$val) { |
|
0 ignored issues
–
show
function (&$val) { $...F8::strtoupper($val); } is of type object<Closure> , but the function expects a object<callable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
895 | 22 | $val = UTF8::strtoupper($val); |
|
896 | 26 | }, |
|
897 | 26 | true |
|
898 | 26 | )->getArray(), |
|
899 | 26 | true |
|
900 | ); |
||
901 | } |
||
902 | |||
903 | 13 | return \in_array( |
|
904 | 13 | UTF8::strtoupper($value), |
|
905 | 13 | $this->walk( |
|
906 | 13 | function (&$val) { |
|
0 ignored issues
–
show
function (&$val) { $...F8::strtoupper($val); } is of type object<Closure> , but the function expects a object<callable> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
Loading history...
|
|||
907 | 11 | $val = UTF8::strtoupper($val); |
|
908 | 13 | }, |
|
909 | 13 | false |
|
910 | 13 | )->getArray(), |
|
911 | 13 | true |
|
912 | ); |
||
913 | } |
||
914 | |||
915 | /** |
||
916 | * Check if the given key/index exists in the array. |
||
917 | * |
||
918 | * @param string|int|float $key <p>key/index to search for</p> |
||
919 | * |
||
920 | * @return bool <p>Returns true if the given key/index exists in the array, false otherwise.</p> |
||
921 | */ |
||
922 | 4 | public function containsKey($key): bool |
|
923 | { |
||
924 | 4 | return $this->offsetExists($key); |
|
925 | } |
||
926 | |||
927 | /** |
||
928 | * Check if all given needles are present in the array as key/index. |
||
929 | * |
||
930 | * @param array $needles <p>The keys you are searching for.</p> |
||
931 | * @param bool $recursive |
||
932 | * |
||
933 | * @return bool <p>Returns true if all the given keys/indexes exists in the array, false otherwise.</p> |
||
934 | */ |
||
935 | 2 | public function containsKeys(array $needles, $recursive = false): bool |
|
936 | { |
||
937 | 2 | if ($recursive === true) { |
|
938 | 2 | return \count( |
|
939 | 2 | \array_intersect($needles, $this->keys(true)->getArray()), |
|
940 | 2 | COUNT_RECURSIVE |
|
941 | ) |
||
942 | === |
||
943 | 2 | \count( |
|
944 | 2 | $needles, |
|
945 | 2 | COUNT_RECURSIVE |
|
946 | ); |
||
947 | } |
||
948 | |||
949 | 1 | return \count( |
|
950 | 1 | \array_intersect($needles, $this->keys()->getArray()), |
|
951 | 1 | COUNT_NORMAL |
|
952 | ) |
||
953 | === |
||
954 | 1 | \count( |
|
955 | 1 | $needles, |
|
956 | 1 | COUNT_NORMAL |
|
957 | ); |
||
958 | } |
||
959 | |||
960 | /** |
||
961 | * Check if all given needles are present in the array as key/index. |
||
962 | * |
||
963 | * @param array $needles <p>The keys you are searching for.</p> |
||
964 | * |
||
965 | * @return bool <p>Returns true if all the given keys/indexes exists in the array, false otherwise.</p> |
||
966 | */ |
||
967 | 1 | public function containsKeysRecursive(array $needles): bool |
|
968 | { |
||
969 | 1 | return $this->containsKeys($needles, true); |
|
970 | } |
||
971 | |||
972 | /** |
||
973 | * alias: for "Arrayy->contains()" |
||
974 | * |
||
975 | * @see Arrayy::contains() |
||
976 | * |
||
977 | * @param string|int|float $value |
||
978 | * |
||
979 | * @return bool |
||
980 | */ |
||
981 | 9 | public function containsValue($value): bool |
|
982 | { |
||
983 | 9 | return $this->contains($value); |
|
984 | } |
||
985 | |||
986 | /** |
||
987 | * alias: for "Arrayy->contains($value, true)" |
||
988 | * |
||
989 | * @see Arrayy::contains() |
||
990 | * |
||
991 | * @param string|int|float $value |
||
992 | * |
||
993 | * @return bool |
||
994 | */ |
||
995 | 18 | public function containsValueRecursive($value): bool |
|
996 | { |
||
997 | 18 | return $this->contains($value, true); |
|
998 | } |
||
999 | |||
1000 | /** |
||
1001 | * Check if all given needles are present in the array. |
||
1002 | * |
||
1003 | * @param array $needles |
||
1004 | * |
||
1005 | * @return bool <p>Returns true if all the given values exists in the array, false otherwise.</p> |
||
1006 | */ |
||
1007 | 1 | public function containsValues(array $needles): bool |
|
1008 | { |
||
1009 | 1 | return \count(\array_intersect($needles, $this->array), COUNT_NORMAL) |
|
1010 | === |
||
1011 | 1 | \count($needles, COUNT_NORMAL); |
|
1012 | } |
||
1013 | |||
1014 | /** |
||
1015 | * Counts all the values of an array |
||
1016 | * |
||
1017 | * @link http://php.net/manual/en/function.array-count-values.php |
||
1018 | * |
||
1019 | * @return static <p> |
||
1020 | * (Immutable) |
||
1021 | * An associative Arrayy-object of values from input as |
||
1022 | * keys and their count as value. |
||
1023 | * </p> |
||
1024 | */ |
||
1025 | 1 | public function countValues(): self |
|
1026 | { |
||
1027 | 1 | return new static(\array_count_values($this->array)); |
|
1028 | } |
||
1029 | |||
1030 | /** |
||
1031 | * Creates an Arrayy object. |
||
1032 | * |
||
1033 | * @param mixed $array |
||
1034 | * |
||
1035 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1036 | */ |
||
1037 | 547 | public static function create($array = []): self |
|
1038 | { |
||
1039 | 547 | return new static($array); |
|
1040 | } |
||
1041 | |||
1042 | /** |
||
1043 | * WARNING: Creates an Arrayy object by reference. |
||
1044 | * |
||
1045 | * @param array $array |
||
1046 | * |
||
1047 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
1048 | */ |
||
1049 | 1 | public function createByReference(array &$array = []): self |
|
1050 | { |
||
1051 | 1 | $array = $this->fallbackForArray($array); |
|
1052 | |||
1053 | 1 | $this->array = &$array; |
|
1054 | |||
1055 | 1 | return $this; |
|
1056 | } |
||
1057 | |||
1058 | /** |
||
1059 | * Create an new Arrayy object via JSON. |
||
1060 | * |
||
1061 | * @param string $json |
||
1062 | * |
||
1063 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1064 | */ |
||
1065 | 5 | public static function createFromJson(string $json) |
|
1066 | { |
||
1067 | 5 | $array = UTF8::json_decode($json, true); |
|
1068 | |||
1069 | 5 | return static::create($array); |
|
1070 | } |
||
1071 | |||
1072 | /** |
||
1073 | * Create an new instance filled with values from an object that have implemented ArrayAccess. |
||
1074 | * |
||
1075 | * @param \ArrayAccess $object <p>Object that implements ArrayAccess</p> |
||
1076 | * |
||
1077 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1078 | */ |
||
1079 | 4 | public static function createFromObject(\ArrayAccess $object) |
|
1080 | { |
||
1081 | // init |
||
1082 | 4 | $array = new static(); |
|
1083 | |||
1084 | 4 | if ($object instanceof self) { |
|
1085 | 4 | $objectArray = $object->getGenerator(); |
|
1086 | } else { |
||
1087 | $objectArray = $object; |
||
1088 | } |
||
1089 | |||
1090 | 4 | foreach ($objectArray as $key => $value) { |
|
1091 | 3 | $array[$key] = $value; |
|
1092 | } |
||
1093 | |||
1094 | 4 | return $array; |
|
1095 | } |
||
1096 | |||
1097 | /** |
||
1098 | * Create an new instance filled with a copy of values from a "Generator"-object. |
||
1099 | * |
||
1100 | * @param \Generator $generator |
||
1101 | * |
||
1102 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1103 | */ |
||
1104 | 4 | public static function createFromGeneratorImmutable(\Generator $generator) |
|
1105 | { |
||
1106 | // init |
||
1107 | 4 | $array = new static(); |
|
1108 | |||
1109 | 4 | foreach ($generator as $key => $value) { |
|
1110 | 3 | $array[$key] = $value; |
|
1111 | } |
||
1112 | |||
1113 | 4 | return $array; |
|
1114 | } |
||
1115 | |||
1116 | /** |
||
1117 | * Create an new instance filled with values from an object. |
||
1118 | * |
||
1119 | * @param object $object |
||
1120 | * |
||
1121 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1122 | */ |
||
1123 | 5 | public static function createFromObjectVars($object): self |
|
1124 | { |
||
1125 | 5 | return new static(self::objectToArray($object)); |
|
1126 | } |
||
1127 | |||
1128 | /** |
||
1129 | * Create an new Arrayy object via string. |
||
1130 | * |
||
1131 | * @param string $str <p>The input string.</p> |
||
1132 | * @param string|null $delimiter <p>The boundary string.</p> |
||
1133 | * @param string|null $regEx <p>Use the $delimiter or the $regEx, so if $pattern is null, $delimiter will be |
||
1134 | * used.</p> |
||
1135 | * |
||
1136 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1137 | */ |
||
1138 | 8 | public static function createFromString(string $str, string $delimiter = null, string $regEx = null) |
|
1139 | { |
||
1140 | 8 | if ($regEx) { |
|
0 ignored issues
–
show
The expression
$regEx of type null|string is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
1141 | 1 | \preg_match_all($regEx, $str, $array); |
|
1142 | |||
1143 | 1 | if (!empty($array)) { |
|
1144 | 1 | $array = $array[0]; |
|
1145 | } |
||
1146 | |||
1147 | } else { |
||
1148 | 7 | $array = \explode($delimiter, $str); |
|
1149 | } |
||
1150 | |||
1151 | // trim all string in the array |
||
1152 | 8 | \array_walk( |
|
1153 | $array, |
||
1154 | 8 | function (&$val) { |
|
1155 | /** @noinspection ReferenceMismatchInspection */ |
||
1156 | 8 | if (\is_string($val)) { |
|
1157 | 8 | $val = \trim($val); |
|
1158 | } |
||
1159 | 8 | } |
|
1160 | ); |
||
1161 | |||
1162 | 8 | return static::create($array); |
|
1163 | } |
||
1164 | |||
1165 | /** |
||
1166 | * Create an new instance containing a range of elements. |
||
1167 | * |
||
1168 | * @param mixed $low <p>First value of the sequence.</p> |
||
1169 | * @param mixed $high <p>The sequence is ended upon reaching the end value.</p> |
||
1170 | * @param int $step <p>Used as the increment between elements in the sequence.</p> |
||
1171 | * |
||
1172 | * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p> |
||
1173 | */ |
||
1174 | 1 | public static function createWithRange($low, $high, int $step = 1) |
|
1175 | { |
||
1176 | 1 | return static::create(\range($low, $high, $step)); |
|
1177 | } |
||
1178 | |||
1179 | /** |
||
1180 | * Custom sort by index via "uksort". |
||
1181 | * |
||
1182 | * @link http://php.net/manual/en/function.uksort.php |
||
1183 | * |
||
1184 | * @param \callable $function |
||
1185 | * |
||
1186 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
1187 | * |
||
1188 | * @throws \InvalidArgumentException |
||
1189 | */ |
||
1190 | 5 | View Code Duplication | public function customSortKeys($function) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
1191 | { |
||
1192 | 5 | if (!\is_callable($function)) { |
|
1193 | throw new \InvalidArgumentException( |
||
1194 | 'Passed function must be callable' |
||
1195 | ); |
||
1196 | } |
||
1197 | |||
1198 | 5 | \uksort($this->array, $function); |
|
1199 | |||
1200 | 5 | return $this; |
|
1201 | } |
||
1202 | |||
1203 | /** |
||
1204 | * Custom sort by value via "usort". |
||
1205 | * |
||
1206 | * @link http://php.net/manual/en/function.usort.php |
||
1207 | * |
||
1208 | * @param \callable $function |
||
1209 | * |
||
1210 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
1211 | * |
||
1212 | * @throws \InvalidArgumentException |
||
1213 | */ |
||
1214 | 5 | View Code Duplication | public function customSortValues($function) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
1215 | { |
||
1216 | 5 | if (!\is_callable($function)) { |
|
1217 | throw new \InvalidArgumentException( |
||
1218 | 'Passed function must be callable' |
||
1219 | ); |
||
1220 | } |
||
1221 | |||
1222 | 5 | \usort($this->array, $function); |
|
1223 | |||
1224 | 5 | return $this; |
|
1225 | } |
||
1226 | |||
1227 | /** |
||
1228 | * Return values that are only in the current array. |
||
1229 | * |
||
1230 | * @param array $array |
||
1231 | * |
||
1232 | * @return static <p>(Immutable)</p> |
||
1233 | */ |
||
1234 | 12 | public function diff(array $array = []) |
|
1235 | { |
||
1236 | 12 | $result = \array_diff($this->array, $array); |
|
1237 | |||
1238 | 12 | return static::create($result); |
|
1239 | } |
||
1240 | |||
1241 | /** |
||
1242 | * Return values that are only in the current multi-dimensional array. |
||
1243 | * |
||
1244 | * @param array $array |
||
1245 | * @param null|array $helperVariableForRecursion <p>(only for internal usage)</p> |
||
1246 | * |
||
1247 | * @return static <p>(Immutable)</p> |
||
1248 | */ |
||
1249 | 1 | public function diffRecursive(array $array = [], $helperVariableForRecursion = null) |
|
1250 | { |
||
1251 | // init |
||
1252 | 1 | $result = []; |
|
1253 | |||
1254 | if ( |
||
1255 | 1 | $helperVariableForRecursion !== null |
|
1256 | && |
||
1257 | 1 | \is_array($helperVariableForRecursion) |
|
1258 | ) { |
||
1259 | 1 | $arrayForTheLoop = $helperVariableForRecursion; |
|
1260 | } else { |
||
1261 | 1 | $arrayForTheLoop = $this->getGenerator(); |
|
1262 | } |
||
1263 | |||
1264 | 1 | foreach ($arrayForTheLoop as $key => $value) { |
|
1265 | 1 | if (\array_key_exists($key, $array)) { |
|
1266 | 1 | if (\is_array($value)) { |
|
1267 | 1 | $recursiveDiff = $this->diffRecursive($array[$key], $value); |
|
1268 | 1 | if (!empty($recursiveDiff)) { |
|
1269 | 1 | $result[$key] = $recursiveDiff; |
|
1270 | } |
||
1271 | 1 | } elseif ($value != $array[$key]) { |
|
1272 | 1 | $result[$key] = $value; |
|
1273 | } |
||
1274 | } else { |
||
1275 | 1 | $result[$key] = $value; |
|
1276 | } |
||
1277 | } |
||
1278 | |||
1279 | 1 | return static::create($result); |
|
1280 | } |
||
1281 | |||
1282 | /** |
||
1283 | * Return values that are only in the new $array. |
||
1284 | * |
||
1285 | * @param array $array |
||
1286 | * |
||
1287 | * @return static <p>(Immutable)</p> |
||
1288 | */ |
||
1289 | 8 | public function diffReverse(array $array = []) |
|
1290 | { |
||
1291 | 8 | $result = \array_diff($array, $this->array); |
|
1292 | |||
1293 | 8 | return static::create($result); |
|
1294 | } |
||
1295 | |||
1296 | /** |
||
1297 | * Divide an array into two arrays. One with keys and the other with values. |
||
1298 | * |
||
1299 | * @return static <p>(Immutable)</p> |
||
1300 | */ |
||
1301 | 1 | public function divide() |
|
1302 | { |
||
1303 | 1 | return static::create( |
|
1304 | [ |
||
1305 | 1 | $this->keys(), |
|
1306 | 1 | $this->values(), |
|
1307 | ] |
||
1308 | ); |
||
1309 | } |
||
1310 | |||
1311 | /** |
||
1312 | * Iterate over the current array and modify the array's value. |
||
1313 | * |
||
1314 | * @param \Closure $closure |
||
1315 | * |
||
1316 | * @return static <p>(Immutable)</p> |
||
1317 | */ |
||
1318 | 4 | View Code Duplication | public function each(\Closure $closure) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
1319 | { |
||
1320 | // init |
||
1321 | 4 | $array = []; |
|
1322 | |||
1323 | 4 | foreach ($this->getGenerator() as $key => $value) { |
|
1324 | 4 | $array[$key] = $closure($value, $key); |
|
1325 | } |
||
1326 | |||
1327 | 4 | return static::create($array); |
|
1328 | } |
||
1329 | |||
1330 | /** |
||
1331 | * Check if a value is in the current array using a closure. |
||
1332 | * |
||
1333 | * @param \Closure $closure |
||
1334 | * |
||
1335 | * @return bool <p>Returns true if the given value is found, false otherwise.</p> |
||
1336 | */ |
||
1337 | 4 | public function exists(\Closure $closure): bool |
|
1338 | { |
||
1339 | // init |
||
1340 | 4 | $isExists = false; |
|
1341 | |||
1342 | 4 | foreach ($this->getGenerator() as $key => $value) { |
|
1343 | 3 | if ($closure($value, $key)) { |
|
1344 | 1 | $isExists = true; |
|
1345 | 3 | break; |
|
1346 | } |
||
1347 | } |
||
1348 | |||
1349 | 4 | return $isExists; |
|
1350 | } |
||
1351 | |||
1352 | /** |
||
1353 | * create a fallback for array |
||
1354 | * |
||
1355 | * 1. use the current array, if it's a array |
||
1356 | * 2. fallback to empty array, if there is nothing |
||
1357 | * 3. call "getArray()" on object, if there is a "Arrayy"-object |
||
1358 | * 4. call "createFromObject()" on object, if there is a "\ArrayAccess"-object |
||
1359 | * 5. call "__toArray()" on object, if the method exists |
||
1360 | * 6. cast a string or object with "__toString()" into an array |
||
1361 | * 7. throw a "InvalidArgumentException"-Exception |
||
1362 | * |
||
1363 | * @param mixed $array |
||
1364 | * |
||
1365 | * @return array |
||
1366 | * |
||
1367 | * @throws \InvalidArgumentException |
||
1368 | */ |
||
1369 | 888 | protected function fallbackForArray(&$array): array |
|
1370 | { |
||
1371 | 888 | if (\is_array($array)) { |
|
1372 | 885 | return $array; |
|
1373 | } |
||
1374 | |||
1375 | 11 | if (!$array) { |
|
1376 | 6 | return []; |
|
1377 | } |
||
1378 | |||
1379 | 10 | $isObject = \is_object($array); |
|
1380 | |||
1381 | 10 | if ($isObject && $array instanceof self) { |
|
1382 | 1 | return $array->getArray(); |
|
1383 | } |
||
1384 | |||
1385 | 9 | if ($isObject && $array instanceof \ArrayAccess) { |
|
1386 | /** @noinspection ReferenceMismatchInspection */ |
||
1387 | return static::createFromObject($array)->getArray(); |
||
1388 | } |
||
1389 | |||
1390 | 9 | if ($isObject && $array instanceof \ArrayObject) { |
|
1391 | return $array->getArrayCopy(); |
||
1392 | } |
||
1393 | |||
1394 | 9 | if ($isObject && \method_exists($array, '__toArray')) { |
|
1395 | return (array)$array->__toArray(); |
||
1396 | } |
||
1397 | |||
1398 | /** @noinspection ReferenceMismatchInspection */ |
||
1399 | if ( |
||
1400 | 9 | \is_string($array) |
|
1401 | || |
||
1402 | 9 | ($isObject && \method_exists($array, '__toString')) |
|
1403 | ) { |
||
1404 | 7 | return [(string)$array]; |
|
1405 | } |
||
1406 | |||
1407 | 2 | throw new \InvalidArgumentException( |
|
1408 | 2 | 'Passed value should be a array' |
|
1409 | ); |
||
1410 | } |
||
1411 | |||
1412 | /** |
||
1413 | * Fill the array until "$num" with "$default" values. |
||
1414 | * |
||
1415 | * @param int $num |
||
1416 | * @param mixed $default |
||
1417 | * |
||
1418 | * @return static <p>(Immutable)</p> |
||
1419 | */ |
||
1420 | 8 | public function fillWithDefaults(int $num, $default = null) |
|
1421 | { |
||
1422 | 8 | if ($num < 0) { |
|
1423 | 1 | throw new \InvalidArgumentException('The $num parameter can only contain non-negative values.'); |
|
1424 | } |
||
1425 | |||
1426 | 7 | $tmpArray = $this->array; |
|
1427 | |||
1428 | 7 | $count = \count($tmpArray); |
|
1429 | |||
1430 | 7 | while ($count < $num) { |
|
1431 | 4 | $tmpArray[] = $default; |
|
1432 | 4 | $count++; |
|
1433 | } |
||
1434 | |||
1435 | 7 | return static::create($tmpArray); |
|
1436 | } |
||
1437 | |||
1438 | /** |
||
1439 | * Find all items in an array that pass the truth test. |
||
1440 | * |
||
1441 | * @param \Closure|null $closure [optional] <p> |
||
1442 | * The callback function to use |
||
1443 | * </p> |
||
1444 | * <p> |
||
1445 | * If no callback is supplied, all entries of |
||
1446 | * input equal to false (see |
||
1447 | * converting to |
||
1448 | * boolean) will be removed. |
||
1449 | * </p> |
||
1450 | * |
||
1451 | * * @param int $flag [optional] <p> |
||
1452 | * Flag determining what arguments are sent to <i>callback</i>: |
||
1453 | * </p><ul> |
||
1454 | * <li> |
||
1455 | * <b>ARRAY_FILTER_USE_KEY</b> [1] - pass key as the only argument |
||
1456 | * to <i>callback</i> instead of the value</span> |
||
1457 | * </li> |
||
1458 | * <li> |
||
1459 | * <b>ARRAY_FILTER_USE_BOTH</b> [2] - pass both value and key as |
||
1460 | * arguments to <i>callback</i> instead of the value</span> |
||
1461 | * </li> |
||
1462 | * </ul> |
||
1463 | * |
||
1464 | * @return static <p>(Immutable)</p> |
||
1465 | */ |
||
1466 | 10 | public function filter($closure = null, int $flag = ARRAY_FILTER_USE_BOTH) |
|
1467 | { |
||
1468 | 10 | if (!$closure) { |
|
1469 | 1 | return $this->clean(); |
|
1470 | } |
||
1471 | |||
1472 | 10 | $array = \array_filter($this->array, $closure, $flag); |
|
1473 | |||
1474 | 10 | return static::create($array); |
|
1475 | } |
||
1476 | |||
1477 | /** |
||
1478 | * Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property |
||
1479 | * within that. |
||
1480 | * |
||
1481 | * @param string $property |
||
1482 | * @param string|string[] $value |
||
1483 | * @param string $comparisonOp |
||
1484 | * <p> |
||
1485 | * 'eq' (equals),<br /> |
||
1486 | * 'gt' (greater),<br /> |
||
1487 | * 'gte' || 'ge' (greater or equals),<br /> |
||
1488 | * 'lt' (less),<br /> |
||
1489 | * 'lte' || 'le' (less or equals),<br /> |
||
1490 | * 'ne' (not equals),<br /> |
||
1491 | * 'contains',<br /> |
||
1492 | * 'notContains',<br /> |
||
1493 | * 'newer' (via strtotime),<br /> |
||
1494 | * 'older' (via strtotime),<br /> |
||
1495 | * </p> |
||
1496 | * |
||
1497 | * @return static <p>(Immutable)</p> |
||
1498 | */ |
||
1499 | 1 | public function filterBy(string $property, $value, string $comparisonOp = null) |
|
1500 | { |
||
1501 | 1 | if (!$comparisonOp) { |
|
0 ignored issues
–
show
The expression
$comparisonOp of type null|string is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
1502 | 1 | $comparisonOp = \is_array($value) ? 'contains' : 'eq'; |
|
1503 | } |
||
1504 | |||
1505 | $ops = [ |
||
1506 | 1 | 'eq' => function ($item, $prop, $value) { |
|
1507 | 1 | return $item[$prop] === $value; |
|
1508 | 1 | }, |
|
1509 | 1 | 'gt' => function ($item, $prop, $value) { |
|
1510 | return $item[$prop] > $value; |
||
1511 | 1 | }, |
|
1512 | 1 | 'ge' => function ($item, $prop, $value) { |
|
1513 | return $item[$prop] >= $value; |
||
1514 | 1 | }, |
|
1515 | 1 | 'gte' => function ($item, $prop, $value) { |
|
1516 | return $item[$prop] >= $value; |
||
1517 | 1 | }, |
|
1518 | 1 | 'lt' => function ($item, $prop, $value) { |
|
1519 | 1 | return $item[$prop] < $value; |
|
1520 | 1 | }, |
|
1521 | 1 | 'le' => function ($item, $prop, $value) { |
|
1522 | return $item[$prop] <= $value; |
||
1523 | 1 | }, |
|
1524 | 1 | 'lte' => function ($item, $prop, $value) { |
|
1525 | return $item[$prop] <= $value; |
||
1526 | 1 | }, |
|
1527 | 1 | 'ne' => function ($item, $prop, $value) { |
|
1528 | return $item[$prop] !== $value; |
||
1529 | 1 | }, |
|
1530 | 1 | 'contains' => function ($item, $prop, $value) { |
|
1531 | 1 | return \in_array($item[$prop], (array)$value, true); |
|
1532 | 1 | }, |
|
1533 | 1 | 'notContains' => function ($item, $prop, $value) { |
|
1534 | return !\in_array($item[$prop], (array)$value, true); |
||
1535 | 1 | }, |
|
1536 | 1 | 'newer' => function ($item, $prop, $value) { |
|
1537 | return \strtotime($item[$prop]) > \strtotime($value); |
||
1538 | 1 | }, |
|
1539 | 1 | 'older' => function ($item, $prop, $value) { |
|
1540 | return \strtotime($item[$prop]) < \strtotime($value); |
||
1541 | 1 | }, |
|
1542 | ]; |
||
1543 | |||
1544 | 1 | $result = \array_values( |
|
1545 | 1 | \array_filter( |
|
1546 | 1 | (array)$this->array, |
|
1547 | 1 | function ($item) use ( |
|
1548 | 1 | $property, |
|
1549 | 1 | $value, |
|
1550 | 1 | $ops, |
|
1551 | 1 | $comparisonOp |
|
1552 | ) { |
||
1553 | 1 | $item = (array)$item; |
|
1554 | 1 | $itemArrayy = new Arrayy($item); |
|
1555 | 1 | $item[$property] = $itemArrayy->get($property, []); |
|
1556 | |||
1557 | 1 | return $ops[$comparisonOp]($item, $property, $value); |
|
1558 | 1 | } |
|
1559 | ) |
||
1560 | ); |
||
1561 | |||
1562 | 1 | return static::create($result); |
|
1563 | } |
||
1564 | |||
1565 | /** |
||
1566 | * Find the first item in an array that passes the truth test, |
||
1567 | * otherwise return false |
||
1568 | * |
||
1569 | * @param \Closure $closure |
||
1570 | * |
||
1571 | * @return mixed|false <p>Return false if we did not find the value.</p> |
||
1572 | */ |
||
1573 | 8 | public function find(\Closure $closure) |
|
1574 | { |
||
1575 | 8 | foreach ($this->getGenerator() as $key => $value) { |
|
1576 | 6 | if ($closure($value, $key)) { |
|
1577 | 6 | return $value; |
|
1578 | } |
||
1579 | } |
||
1580 | |||
1581 | 3 | return false; |
|
1582 | } |
||
1583 | |||
1584 | /** |
||
1585 | * find by ... |
||
1586 | * |
||
1587 | * @param string $property |
||
1588 | * @param string|string[] $value |
||
1589 | * @param string $comparisonOp |
||
1590 | * |
||
1591 | * @return static <p>(Immutable)</p> |
||
1592 | */ |
||
1593 | public function findBy(string $property, $value, string $comparisonOp = 'eq') |
||
1594 | { |
||
1595 | return $this->filterBy($property, $value, $comparisonOp); |
||
1596 | } |
||
1597 | |||
1598 | /** |
||
1599 | * Get the first value from the current array. |
||
1600 | * |
||
1601 | * @return mixed <p>Return null if there wasn't a element.</p> |
||
1602 | */ |
||
1603 | 13 | public function first() |
|
1604 | { |
||
1605 | 13 | $tmpArray = $this->array; |
|
1606 | 13 | $result = \array_shift($tmpArray); |
|
1607 | |||
1608 | 13 | return $result; |
|
1609 | } |
||
1610 | |||
1611 | /** |
||
1612 | * Get the first value(s) from the current array. |
||
1613 | * |
||
1614 | * @param int|null $number <p>How many values you will take?</p> |
||
1615 | * |
||
1616 | * @return static <p>(Immutable)</p> |
||
1617 | */ |
||
1618 | 28 | public function firstsImmutable(int $number = null) |
|
1619 | { |
||
1620 | 28 | if ($number === null) { |
|
1621 | 7 | $arrayTmp = $this->array; |
|
1622 | 7 | $array = (array)\array_shift($arrayTmp); |
|
1623 | } else { |
||
1624 | 21 | $number = (int)$number; |
|
1625 | 21 | $arrayTmp = $this->array; |
|
1626 | 21 | $array = \array_splice($arrayTmp, 0, $number, true); |
|
1627 | } |
||
1628 | |||
1629 | 28 | return static::create($array); |
|
1630 | } |
||
1631 | |||
1632 | /** |
||
1633 | * Get the first value(s) from the current array. |
||
1634 | * |
||
1635 | * @param int|null $number <p>How many values you will take?</p> |
||
1636 | * |
||
1637 | * @return static <p>(Mutable)</p> |
||
1638 | */ |
||
1639 | 26 | public function firstsMutable(int $number = null) |
|
1640 | { |
||
1641 | 26 | if ($number === null) { |
|
1642 | 11 | $this->array = (array)\array_shift($this->array); |
|
1643 | } else { |
||
1644 | 15 | $number = (int)$number; |
|
1645 | 15 | $this->array = \array_splice($this->array, 0, $number, true); |
|
1646 | } |
||
1647 | |||
1648 | 26 | return $this; |
|
1649 | } |
||
1650 | |||
1651 | /** |
||
1652 | * Exchanges all keys with their associated values in an array. |
||
1653 | * |
||
1654 | * @return static <p>(Immutable)</p> |
||
1655 | */ |
||
1656 | 1 | public function flip() |
|
1657 | { |
||
1658 | 1 | $result = \array_flip($this->array); |
|
1659 | |||
1660 | 1 | return static::create($result); |
|
1661 | } |
||
1662 | |||
1663 | /** |
||
1664 | * Get a value from an array (optional using dot-notation). |
||
1665 | * |
||
1666 | * @param mixed $key <p>The key to look for.</p> |
||
1667 | * @param mixed $fallback <p>Value to fallback to.</p> |
||
1668 | * @param array $array <p>The array to get from, if it's set to "null" we use the current array from the |
||
1669 | * class.</p> |
||
1670 | * |
||
1671 | * @return mixed|static |
||
1672 | */ |
||
1673 | 882 | public function get($key, $fallback = null, array $array = null) |
|
1674 | { |
||
1675 | 882 | if ($array !== null) { |
|
1676 | 4 | $usedArray = $array; |
|
1677 | } else { |
||
1678 | 882 | $usedArray = $this->array; |
|
1679 | } |
||
1680 | |||
1681 | 882 | if ($key === null) { |
|
1682 | 1 | return static::create($usedArray); |
|
1683 | } |
||
1684 | |||
1685 | // php cast "bool"-index into "int"-index |
||
1686 | 882 | if ((bool)$key === $key) { |
|
1687 | 3 | $key = (int)$key; |
|
1688 | } |
||
1689 | |||
1690 | 882 | if (\array_key_exists($key, $usedArray) === true) { |
|
1691 | 58 | if (\is_array($usedArray[$key])) { |
|
1692 | 8 | return static::create($usedArray[$key]); |
|
1693 | } |
||
1694 | |||
1695 | 52 | return $usedArray[$key]; |
|
1696 | } |
||
1697 | |||
1698 | // Crawl through array, get key according to object or not |
||
1699 | 878 | foreach (\explode($this->pathSeparator, (string)$key) as $segment) { |
|
1700 | 878 | if (!isset($usedArray[$segment])) { |
|
1701 | 878 | return $fallback instanceof \Closure ? $fallback() : $fallback; |
|
1702 | } |
||
1703 | |||
1704 | 6 | $usedArray = $usedArray[$segment]; |
|
1705 | } |
||
1706 | |||
1707 | 6 | if (\is_array($usedArray)) { |
|
1708 | 1 | return static::create($usedArray); |
|
1709 | } |
||
1710 | |||
1711 | 6 | return $usedArray; |
|
1712 | } |
||
1713 | |||
1714 | /** |
||
1715 | * Get the current array from the "Arrayy"-object. |
||
1716 | * |
||
1717 | * @return array |
||
1718 | */ |
||
1719 | 577 | public function getArray(): array |
|
1720 | { |
||
1721 | 577 | return $this->array; |
|
1722 | } |
||
1723 | |||
1724 | /** |
||
1725 | * Get the current array from the "Arrayy"-object as generator. |
||
1726 | * |
||
1727 | * @return \Generator |
||
1728 | */ |
||
1729 | 125 | public function getGenerator(): \Generator |
|
1730 | { |
||
1731 | 125 | yield from $this->array; |
|
1732 | 93 | } |
|
1733 | |||
1734 | /** |
||
1735 | * Returns the values from a single column of the input array, identified by |
||
1736 | * the $columnKey, can be used to extract data-columns from multi-arrays. |
||
1737 | * |
||
1738 | * Info: Optionally, you may provide an $indexKey to index the values in the returned |
||
1739 | * array by the values from the $indexKey column in the input array. |
||
1740 | * |
||
1741 | * @param mixed $columnKey |
||
1742 | * @param mixed $indexKey |
||
1743 | * |
||
1744 | * @return static <p>(Immutable)</p> |
||
1745 | */ |
||
1746 | 1 | public function getColumn($columnKey = null, $indexKey = null) |
|
1747 | { |
||
1748 | 1 | $result = \array_column($this->array, $columnKey, $indexKey); |
|
1749 | |||
1750 | 1 | return static::create($result); |
|
1751 | } |
||
1752 | |||
1753 | /** |
||
1754 | * Get correct PHP constant for direction. |
||
1755 | * |
||
1756 | * @param int|string $direction |
||
1757 | * |
||
1758 | * @return int |
||
1759 | */ |
||
1760 | 38 | protected function getDirection($direction): int |
|
1761 | { |
||
1762 | 38 | if (\is_string($direction)) { |
|
1763 | 10 | $direction = \strtolower($direction); |
|
1764 | |||
1765 | 10 | if ($direction === 'desc') { |
|
1766 | 2 | $direction = SORT_DESC; |
|
1767 | } else { |
||
1768 | 8 | $direction = SORT_ASC; |
|
1769 | } |
||
1770 | } |
||
1771 | |||
1772 | if ( |
||
1773 | 38 | $direction !== SORT_DESC |
|
1774 | && |
||
1775 | 38 | $direction !== SORT_ASC |
|
1776 | ) { |
||
1777 | $direction = SORT_ASC; |
||
1778 | } |
||
1779 | |||
1780 | 38 | return $direction; |
|
1781 | } |
||
1782 | |||
1783 | /** |
||
1784 | * alias: for "Arrayy->keys()" |
||
1785 | * |
||
1786 | * @see Arrayy::keys() |
||
1787 | * |
||
1788 | * @return static <p>(Immutable)</p> |
||
1789 | */ |
||
1790 | 1 | public function getKeys() |
|
1791 | { |
||
1792 | 1 | return $this->keys(); |
|
1793 | } |
||
1794 | |||
1795 | /** |
||
1796 | * Get the current array from the "Arrayy"-object as object. |
||
1797 | * |
||
1798 | * @return \stdClass (object) |
||
1799 | */ |
||
1800 | 4 | public function getObject(): \stdClass |
|
1801 | { |
||
1802 | 4 | return self::arrayToObject($this->getArray()); |
|
1803 | } |
||
1804 | |||
1805 | /** |
||
1806 | * @return array|Property[] |
||
1807 | */ |
||
1808 | 8 | protected function getPublicProperties(): array |
|
1809 | { |
||
1810 | 8 | static $PROPERTY_CACHE = []; |
|
1811 | 8 | $cacheKey = 'Class::' . static::class; |
|
1812 | |||
1813 | 8 | if (isset($PROPERTY_CACHE[$cacheKey])) { |
|
1814 | 7 | return $PROPERTY_CACHE[$cacheKey]; |
|
1815 | } |
||
1816 | |||
1817 | // init |
||
1818 | 2 | $properties = []; |
|
1819 | |||
1820 | 2 | $reflector = new \ReflectionClass($this); |
|
1821 | 2 | $factory = \phpDocumentor\Reflection\DocBlockFactory::createInstance(); |
|
1822 | 2 | $docblock = $factory->create($reflector->getDocComment()); |
|
1823 | 2 | foreach ($docblock->getTagsByName('property') as $tag) { |
|
1824 | /* @var $tag \phpDocumentor\Reflection\DocBlock\Tags\Property */ |
||
1825 | 2 | $properties[$tag->getVariableName()] = Property::fromPhpDocumentorProperty($tag); |
|
1826 | } |
||
1827 | |||
1828 | 2 | return $PROPERTY_CACHE[$cacheKey] = $properties; |
|
1829 | } |
||
1830 | |||
1831 | /** |
||
1832 | * alias: for "Arrayy->randomImmutable()" |
||
1833 | * |
||
1834 | * @see Arrayy::randomImmutable() |
||
1835 | * |
||
1836 | * @return static <p>(Immutable)</p> |
||
1837 | */ |
||
1838 | 4 | public function getRandom() |
|
1839 | { |
||
1840 | 4 | return $this->randomImmutable(); |
|
1841 | } |
||
1842 | |||
1843 | /** |
||
1844 | * alias: for "Arrayy->randomKey()" |
||
1845 | * |
||
1846 | * @see Arrayy::randomKey() |
||
1847 | * |
||
1848 | * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p> |
||
1849 | */ |
||
1850 | 3 | public function getRandomKey() |
|
1851 | { |
||
1852 | 3 | return $this->randomKey(); |
|
1853 | } |
||
1854 | |||
1855 | /** |
||
1856 | * alias: for "Arrayy->randomKeys()" |
||
1857 | * |
||
1858 | * @see Arrayy::randomKeys() |
||
1859 | * |
||
1860 | * @param int $number |
||
1861 | * |
||
1862 | * @return static <p>(Immutable)</p> |
||
1863 | */ |
||
1864 | 8 | public function getRandomKeys(int $number) |
|
1865 | { |
||
1866 | 8 | return $this->randomKeys($number); |
|
1867 | } |
||
1868 | |||
1869 | /** |
||
1870 | * alias: for "Arrayy->randomValue()" |
||
1871 | * |
||
1872 | * @see Arrayy::randomValue() |
||
1873 | * |
||
1874 | * @return mixed <p>get a random value or null if there wasn't a value.</p> |
||
1875 | */ |
||
1876 | 3 | public function getRandomValue() |
|
1877 | { |
||
1878 | 3 | return $this->randomValue(); |
|
1879 | } |
||
1880 | |||
1881 | /** |
||
1882 | * alias: for "Arrayy->randomValues()" |
||
1883 | * |
||
1884 | * @see Arrayy::randomValues() |
||
1885 | * |
||
1886 | * @param int $number |
||
1887 | * |
||
1888 | * @return static <p>(Immutable)</p> |
||
1889 | */ |
||
1890 | 6 | public function getRandomValues(int $number) |
|
1891 | { |
||
1892 | 6 | return $this->randomValues($number); |
|
1893 | } |
||
1894 | |||
1895 | /** |
||
1896 | * Group values from a array according to the results of a closure. |
||
1897 | * |
||
1898 | * @param \callable $grouper <p>A callable function name.</p> |
||
1899 | * @param bool $saveKeys |
||
1900 | * |
||
1901 | * @return static <p>(Immutable)</p> |
||
1902 | */ |
||
1903 | 4 | public function group($grouper, bool $saveKeys = false) |
|
1904 | { |
||
1905 | // init |
||
1906 | 4 | $result = []; |
|
1907 | |||
1908 | // Iterate over values, group by property/results from closure. |
||
1909 | 4 | foreach ($this->getGenerator() as $key => $value) { |
|
1910 | |||
1911 | 4 | $groupKey = \is_callable($grouper) ? $grouper($value, $key) : $this->get($grouper, null, $this->array); |
|
1912 | 4 | $newValue = $this->get($groupKey, null, $result); |
|
1913 | |||
1914 | 4 | if ($groupKey instanceof self) { |
|
1915 | $groupKey = $groupKey->getArray(); |
||
1916 | } |
||
1917 | |||
1918 | 4 | if ($newValue instanceof self) { |
|
1919 | 4 | $newValue = $newValue->getArray(); |
|
1920 | } |
||
1921 | |||
1922 | // Add to results. |
||
1923 | 4 | if ($groupKey !== null) { |
|
1924 | 3 | if ($saveKeys) { |
|
1925 | 2 | $result[$groupKey] = $newValue; |
|
1926 | 2 | $result[$groupKey][$key] = $value; |
|
1927 | } else { |
||
1928 | 1 | $result[$groupKey] = $newValue; |
|
1929 | 4 | $result[$groupKey][] = $value; |
|
1930 | } |
||
1931 | } |
||
1932 | |||
1933 | } |
||
1934 | |||
1935 | 4 | return static::create($result); |
|
1936 | } |
||
1937 | |||
1938 | /** |
||
1939 | * Check if an array has a given key. |
||
1940 | * |
||
1941 | * @param mixed $key |
||
1942 | * |
||
1943 | * @return bool |
||
1944 | */ |
||
1945 | 23 | public function has($key): bool |
|
1946 | { |
||
1947 | 23 | static $UN_FOUND = null; |
|
1948 | |||
1949 | 23 | if ($UN_FOUND === null) { |
|
1950 | // Generate unique string to use as marker. |
||
1951 | 1 | $UN_FOUND = \uniqid('arrayy', true); |
|
1952 | } |
||
1953 | |||
1954 | 23 | return $this->get($key, $UN_FOUND) !== $UN_FOUND; |
|
1955 | } |
||
1956 | |||
1957 | /** |
||
1958 | * Implodes the values of this array. |
||
1959 | * |
||
1960 | * @param string $glue |
||
1961 | * |
||
1962 | * @return string |
||
1963 | */ |
||
1964 | 27 | public function implode(string $glue = ''): string |
|
1965 | { |
||
1966 | 27 | return $this->implode_recursive($glue, $this->array, false); |
|
1967 | } |
||
1968 | |||
1969 | /** |
||
1970 | * Implodes the keys of this array. |
||
1971 | * |
||
1972 | * @param string $glue |
||
1973 | * |
||
1974 | * @return string |
||
1975 | */ |
||
1976 | 8 | public function implodeKeys(string $glue = ''): string |
|
1977 | { |
||
1978 | 8 | return $this->implode_recursive($glue, $this->array, true); |
|
1979 | } |
||
1980 | |||
1981 | /** |
||
1982 | * @param mixed $glue |
||
1983 | * @param string|array|static $pieces |
||
1984 | * @param bool $useKeys |
||
1985 | * |
||
1986 | * @return string |
||
1987 | */ |
||
1988 | 35 | protected function implode_recursive($glue = '', $pieces = [], bool $useKeys = false): string |
|
1989 | { |
||
1990 | 35 | if ($pieces instanceof self) { |
|
1991 | 1 | $pieces = $pieces->getArray(); |
|
1992 | } |
||
1993 | |||
1994 | 35 | if (\is_array($pieces)) { |
|
1995 | 35 | $pieces_count = \count($pieces, COUNT_NORMAL); |
|
1996 | 35 | $pieces_count_not_zero = $pieces_count > 0; |
|
1997 | |||
1998 | 35 | return \implode( |
|
1999 | 35 | $glue, |
|
2000 | 35 | \array_map( |
|
2001 | 35 | [$this, 'implode_recursive'], |
|
2002 | 35 | \array_fill(0, ($pieces_count_not_zero ? $pieces_count : 1), $glue), |
|
2003 | 35 | ($useKeys === true && $pieces_count_not_zero ? $this->array_keys_recursive($pieces) : $pieces) |
|
2004 | ) |
||
2005 | ); |
||
2006 | } |
||
2007 | |||
2008 | 35 | return (string)$pieces; |
|
2009 | } |
||
2010 | |||
2011 | /** |
||
2012 | * @param mixed $needle <p> |
||
2013 | * The searched value. |
||
2014 | * </p> |
||
2015 | * <p> |
||
2016 | * If needle is a string, the comparison is done |
||
2017 | * in a case-sensitive manner. |
||
2018 | * </p> |
||
2019 | * @param array $haystack <p> |
||
2020 | * The array. |
||
2021 | * </p> |
||
2022 | * @param bool $strict [optional] <p> |
||
2023 | * If the third parameter strict is set to true |
||
2024 | * then the in_array function will also check the |
||
2025 | * types of the |
||
2026 | * needle in the haystack. |
||
2027 | * </p> |
||
2028 | * |
||
2029 | * @return bool true if needle is found in the array, false otherwise. |
||
2030 | */ |
||
2031 | 44 | protected function in_array_recursive($needle, array $haystack = null, $strict = true): bool |
|
2032 | { |
||
2033 | 44 | if ($haystack === null) { |
|
2034 | $haystack = $this->getGenerator(); |
||
2035 | } |
||
2036 | |||
2037 | 44 | foreach ($haystack as $item) { |
|
2038 | |||
2039 | 36 | if (\is_array($item) === true) { |
|
2040 | 8 | $returnTmp = $this->in_array_recursive($needle, $item, $strict); |
|
2041 | } else { |
||
2042 | 36 | $returnTmp = ($strict === true ? $item === $needle : $item == $needle); |
|
2043 | } |
||
2044 | |||
2045 | 36 | if ($returnTmp === true) { |
|
2046 | 36 | return true; |
|
2047 | } |
||
2048 | } |
||
2049 | |||
2050 | 18 | return false; |
|
2051 | } |
||
2052 | |||
2053 | /** |
||
2054 | * Given a list and an iterate-function that returns |
||
2055 | * a key for each element in the list (or a property name), |
||
2056 | * returns an object with an index of each item. |
||
2057 | * |
||
2058 | * @param mixed $key |
||
2059 | * |
||
2060 | * @return static <p>(Immutable)</p> |
||
2061 | */ |
||
2062 | 4 | public function indexBy($key) |
|
2063 | { |
||
2064 | // init |
||
2065 | 4 | $results = []; |
|
2066 | |||
2067 | 4 | foreach ($this->getGenerator() as $a) { |
|
2068 | 4 | if (\array_key_exists($key, $a) === true) { |
|
2069 | 4 | $results[$a[$key]] = $a; |
|
2070 | } |
||
2071 | } |
||
2072 | |||
2073 | 4 | return static::create($results); |
|
2074 | } |
||
2075 | |||
2076 | /** |
||
2077 | * alias: for "Arrayy->searchIndex()" |
||
2078 | * |
||
2079 | * @see Arrayy::searchIndex() |
||
2080 | * |
||
2081 | * @param mixed $value <p>The value to search for.</p> |
||
2082 | * |
||
2083 | * @return mixed |
||
2084 | */ |
||
2085 | 4 | public function indexOf($value) |
|
2086 | { |
||
2087 | 4 | return $this->searchIndex($value); |
|
2088 | } |
||
2089 | |||
2090 | /** |
||
2091 | * Get everything but the last..$to items. |
||
2092 | * |
||
2093 | * @param int $to |
||
2094 | * |
||
2095 | * @return static <p>(Immutable)</p> |
||
2096 | */ |
||
2097 | 12 | public function initial(int $to = 1) |
|
2098 | { |
||
2099 | 12 | return $this->firstsImmutable(\count($this->array, COUNT_NORMAL) - $to); |
|
2100 | } |
||
2101 | |||
2102 | /** |
||
2103 | * @param mixed $value |
||
2104 | */ |
||
2105 | protected function internalGetArray(&$value) |
||
2106 | { |
||
2107 | if ($value instanceof self) { |
||
2108 | |||
2109 | $valueTmp = $value->getArray(); |
||
2110 | if (\count($valueTmp, COUNT_NORMAL) === 0) { |
||
2111 | $value = []; |
||
2112 | } else { |
||
2113 | /** @noinspection PhpUnusedLocalVariableInspection */ |
||
2114 | $value = &$valueTmp; |
||
2115 | } |
||
2116 | |||
2117 | } elseif ( |
||
2118 | \class_exists('JsonSerializable') |
||
2119 | && |
||
2120 | $value instanceof \JsonSerializable |
||
0 ignored issues
–
show
The class
JsonSerializable does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed.
Loading history...
|
|||
2121 | ) { |
||
2122 | |||
2123 | /** @noinspection PhpUnusedLocalVariableInspection */ |
||
2124 | $value = &$value->jsonSerialize(); |
||
2125 | |||
2126 | } |
||
2127 | } |
||
2128 | |||
2129 | /** |
||
2130 | * Internal mechanics of remove method. |
||
2131 | * |
||
2132 | * @param mixed $key |
||
2133 | * |
||
2134 | * @return bool |
||
2135 | */ |
||
2136 | 18 | protected function internalRemove($key): bool |
|
2137 | { |
||
2138 | 18 | $path = \explode($this->pathSeparator, (string)$key); |
|
2139 | |||
2140 | // Crawl though the keys |
||
2141 | 18 | while (\count($path, COUNT_NORMAL) > 1) { |
|
2142 | $key = \array_shift($path); |
||
2143 | |||
2144 | if (!$this->has($key)) { |
||
2145 | return false; |
||
2146 | } |
||
2147 | |||
2148 | $this->array = &$this->array[$key]; |
||
2149 | } |
||
2150 | |||
2151 | 18 | $key = \array_shift($path); |
|
2152 | |||
2153 | 18 | unset($this->array[$key]); |
|
2154 | |||
2155 | 18 | return true; |
|
2156 | } |
||
2157 | |||
2158 | /** |
||
2159 | * Internal mechanic of set method. |
||
2160 | * |
||
2161 | * @param null|string $key |
||
2162 | * @param mixed $value |
||
2163 | * |
||
2164 | * @return bool |
||
2165 | */ |
||
2166 | 777 | protected function internalSet($key, $value): bool |
|
2167 | { |
||
2168 | 777 | if ($this->checkPropertyTypes === true) { |
|
2169 | 6 | if (isset($this->properties[$key]) === false) { |
|
2170 | throw new \InvalidArgumentException('The key ' . $key . ' does not exists as @property in the class (' . \get_class($this) . ').'); |
||
2171 | } |
||
2172 | |||
2173 | 6 | $this->properties[$key]->checkType($value); |
|
2174 | } |
||
2175 | |||
2176 | 776 | if ($key === null) { |
|
2177 | return false; |
||
2178 | } |
||
2179 | |||
2180 | // init |
||
2181 | 776 | $array =& $this->array; |
|
2182 | 776 | $path = \explode($this->pathSeparator, (string)$key); |
|
2183 | |||
2184 | // Crawl through the keys |
||
2185 | 776 | while (\count($path, COUNT_NORMAL) > 1) { |
|
2186 | 3 | $key = \array_shift($path); |
|
2187 | |||
2188 | 3 | $array =& $array[$key]; |
|
2189 | } |
||
2190 | |||
2191 | 776 | $array[\array_shift($path)] = $value; |
|
2192 | |||
2193 | 776 | return true; |
|
2194 | } |
||
2195 | |||
2196 | /** |
||
2197 | * Return an array with all elements found in input array. |
||
2198 | * |
||
2199 | * @param array $search |
||
2200 | * |
||
2201 | * @return static <p>(Immutable)</p> |
||
2202 | */ |
||
2203 | 2 | public function intersection(array $search) |
|
2204 | { |
||
2205 | 2 | return static::create(\array_values(\array_intersect($this->array, $search))); |
|
2206 | } |
||
2207 | |||
2208 | /** |
||
2209 | * Return a boolean flag which indicates whether the two input arrays have any common elements. |
||
2210 | * |
||
2211 | * @param array $search |
||
2212 | * |
||
2213 | * @return bool |
||
2214 | */ |
||
2215 | 1 | public function intersects(array $search): bool |
|
2216 | { |
||
2217 | 1 | return \count($this->intersection($search)->array, COUNT_NORMAL) > 0; |
|
2218 | } |
||
2219 | |||
2220 | /** |
||
2221 | * Invoke a function on all of an array's values. |
||
2222 | * |
||
2223 | * @param mixed $callable |
||
2224 | * @param mixed $arguments |
||
2225 | * |
||
2226 | * @return static <p>(Immutable)</p> |
||
2227 | */ |
||
2228 | 1 | public function invoke($callable, $arguments = []) |
|
2229 | { |
||
2230 | // If one argument given for each iteration, create an array for it. |
||
2231 | 1 | if (!\is_array($arguments)) { |
|
2232 | 1 | $arguments = StaticArrayy::repeat( |
|
2233 | 1 | $arguments, |
|
2234 | 1 | \count($this->array, COUNT_NORMAL) |
|
2235 | 1 | )->getArray(); |
|
2236 | } |
||
2237 | |||
2238 | // If the callable has arguments, pass them. |
||
2239 | 1 | if ($arguments) { |
|
0 ignored issues
–
show
The expression
$arguments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using
Loading history...
|
|||
2240 | 1 | $array = \array_map($callable, $this->array, $arguments); |
|
2241 | } else { |
||
2242 | 1 | $array = \array_map($callable, $this->array); |
|
2243 | } |
||
2244 | |||
2245 | 1 | return static::create($array); |
|
2246 | } |
||
2247 | |||
2248 | /** |
||
2249 | * Check whether array is associative or not. |
||
2250 | * |
||
2251 | * @param bool $recursive |
||
2252 | * |
||
2253 | * @return bool <p>Returns true if associative, false otherwise.</p> |
||
2254 | */ |
||
2255 | 15 | public function isAssoc(bool $recursive = false): bool |
|
2256 | { |
||
2257 | 15 | if ($this->isEmpty()) { |
|
2258 | 3 | return false; |
|
2259 | } |
||
2260 | |||
2261 | 13 | foreach ($this->keys($recursive)->getGenerator() as $key) { |
|
2262 | 13 | if (!\is_string($key)) { |
|
2263 | 13 | return false; |
|
2264 | } |
||
2265 | } |
||
2266 | |||
2267 | 3 | return true; |
|
2268 | } |
||
2269 | |||
2270 | /** |
||
2271 | * Check whether the array is empty or not. |
||
2272 | * |
||
2273 | * @return bool <p>Returns true if empty, false otherwise.</p> |
||
2274 | */ |
||
2275 | 92 | public function isEmpty(): bool |
|
2276 | { |
||
2277 | 92 | return !$this->array; |
|
2278 | } |
||
2279 | |||
2280 | /** |
||
2281 | * Check if the current array is equal to the given "$array" or not. |
||
2282 | * |
||
2283 | * @param array $array |
||
2284 | * |
||
2285 | * @return bool |
||
2286 | */ |
||
2287 | public function isEqual(array $array): bool |
||
2288 | { |
||
2289 | return ($this->array === $array); |
||
2290 | } |
||
2291 | |||
2292 | /** |
||
2293 | * Check if the current array is a multi-array. |
||
2294 | * |
||
2295 | * @return bool |
||
2296 | */ |
||
2297 | 14 | public function isMultiArray(): bool |
|
2298 | { |
||
2299 | return !( |
||
2300 | 14 | \count($this->array, COUNT_NORMAL) |
|
2301 | === |
||
2302 | 14 | \count($this->array, COUNT_RECURSIVE) |
|
2303 | ); |
||
2304 | } |
||
2305 | |||
2306 | /** |
||
2307 | * Check whether array is numeric or not. |
||
2308 | * |
||
2309 | * @return bool <p>Returns true if numeric, false otherwise.</p> |
||
2310 | */ |
||
2311 | 5 | public function isNumeric(): bool |
|
2312 | { |
||
2313 | 5 | if ($this->isEmpty()) { |
|
2314 | 2 | return false; |
|
2315 | } |
||
2316 | |||
2317 | 4 | foreach ($this->keys()->getGenerator() as $key) { |
|
2318 | 4 | if (!\is_int($key)) { |
|
2319 | 4 | return false; |
|
2320 | } |
||
2321 | } |
||
2322 | |||
2323 | 2 | return true; |
|
2324 | } |
||
2325 | |||
2326 | /** |
||
2327 | * Check if the current array is sequential [0, 1, 2, 3, 4, 5 ...] or not. |
||
2328 | * |
||
2329 | * @param bool $recursive |
||
2330 | * |
||
2331 | * @return bool |
||
2332 | */ |
||
2333 | 1 | public function isSequential(bool $recursive = false): bool |
|
2334 | { |
||
2335 | |||
2336 | // recursive |
||
2337 | |||
2338 | 1 | if ($recursive === true) { |
|
2339 | return $this->array_keys_recursive($this->array) |
||
2340 | === |
||
2341 | \range(0, \count($this->array, COUNT_RECURSIVE) - 1); |
||
2342 | } |
||
2343 | |||
2344 | // non recursive |
||
2345 | |||
2346 | 1 | return \array_keys($this->array) |
|
2347 | === |
||
2348 | 1 | \range(0, \count($this->array, COUNT_NORMAL) - 1); |
|
2349 | } |
||
2350 | |||
2351 | /** |
||
2352 | * @return array |
||
2353 | */ |
||
2354 | public function jsonSerialize(): array |
||
2355 | { |
||
2356 | return $this->getArray(); |
||
2357 | } |
||
2358 | |||
2359 | /** |
||
2360 | * Get all keys from the current array. |
||
2361 | * |
||
2362 | * @param bool $recursive [optional] <p> |
||
2363 | * Get all keys, also from all sub-arrays from an multi-dimensional array. |
||
2364 | * </p> |
||
2365 | * @param mixed $search_value [optional] <p> |
||
2366 | * If specified, then only keys containing these values are returned. |
||
2367 | * </p> |
||
2368 | * @param bool $strict [optional] <p> |
||
2369 | * Determines if strict comparison (===) should be used during the search. |
||
2370 | * </p> |
||
2371 | * |
||
2372 | * @return static <p>(Immutable) An array of all the keys in input.</p> |
||
2373 | */ |
||
2374 | 26 | public function keys(bool $recursive = false, $search_value = null, bool $strict = true) |
|
2375 | { |
||
2376 | |||
2377 | // recursive |
||
2378 | |||
2379 | 26 | if ($recursive === true) { |
|
2380 | 3 | if ($search_value === null) { |
|
2381 | 3 | $array = $this->array_keys_recursive($this->array); |
|
2382 | } else { |
||
2383 | $array = $this->array_keys_recursive($this->array, $search_value, $strict); |
||
2384 | } |
||
2385 | |||
2386 | 3 | return static::create($array); |
|
2387 | } |
||
2388 | |||
2389 | // non recursive |
||
2390 | |||
2391 | 25 | if ($search_value === null) { |
|
2392 | 25 | $array = \array_keys($this->array); |
|
2393 | } else { |
||
2394 | $array = \array_keys($this->array, $search_value, $strict); |
||
2395 | } |
||
2396 | |||
2397 | 25 | return static::create($array); |
|
2398 | } |
||
2399 | |||
2400 | /** |
||
2401 | * Sort an array by key in reverse order. |
||
2402 | * |
||
2403 | * @param int $sort_flags [optional] <p> |
||
2404 | * You may modify the behavior of the sort using the optional |
||
2405 | * parameter sort_flags, for details |
||
2406 | * see sort. |
||
2407 | * </p> |
||
2408 | * |
||
2409 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
2410 | */ |
||
2411 | 4 | public function krsort(int $sort_flags = 0) |
|
2412 | { |
||
2413 | 4 | krsort($this->array, $sort_flags); |
|
2414 | |||
2415 | 4 | return $this; |
|
2416 | } |
||
2417 | |||
2418 | /** |
||
2419 | * Get the last value from the current array. |
||
2420 | * |
||
2421 | * @return mixed <p>Return null if there wasn't a element.</p> |
||
2422 | */ |
||
2423 | 4 | public function last() |
|
2424 | { |
||
2425 | 4 | return $this->pop(); |
|
2426 | } |
||
2427 | |||
2428 | /** |
||
2429 | * Get the last value(s) from the current array. |
||
2430 | * |
||
2431 | * @param int|null $number |
||
2432 | * |
||
2433 | * @return static <p>(Immutable)</p> |
||
2434 | */ |
||
2435 | 13 | public function lastsImmutable(int $number = null) |
|
2436 | { |
||
2437 | 13 | if ($this->isEmpty()) { |
|
2438 | 1 | return static::create(); |
|
2439 | } |
||
2440 | |||
2441 | 12 | if ($number === null) { |
|
2442 | 8 | $poppedValue = $this->pop(); |
|
2443 | |||
2444 | 8 | if ($poppedValue === null) { |
|
2445 | 1 | $poppedValue = [$poppedValue]; |
|
2446 | } else { |
||
2447 | 7 | $poppedValue = (array)$poppedValue; |
|
2448 | } |
||
2449 | |||
2450 | 8 | $arrayy = static::create($poppedValue); |
|
2451 | } else { |
||
2452 | 4 | $number = (int)$number; |
|
2453 | 4 | $arrayy = $this->rest(-$number); |
|
2454 | } |
||
2455 | |||
2456 | 12 | return $arrayy; |
|
2457 | } |
||
2458 | |||
2459 | /** |
||
2460 | * Get the last value(s) from the current array. |
||
2461 | * |
||
2462 | * @param int|null $number |
||
2463 | * |
||
2464 | * @return static <p>(Mutable)</p> |
||
2465 | */ |
||
2466 | 13 | public function lastsMutable(int $number = null) |
|
2467 | { |
||
2468 | 13 | if ($this->isEmpty()) { |
|
2469 | 1 | return $this; |
|
2470 | } |
||
2471 | |||
2472 | 12 | if ($number === null) { |
|
2473 | 8 | $poppedValue = $this->pop(); |
|
2474 | |||
2475 | 8 | if ($poppedValue === null) { |
|
2476 | 1 | $poppedValue = [$poppedValue]; |
|
2477 | } else { |
||
2478 | 7 | $poppedValue = (array)$poppedValue; |
|
2479 | } |
||
2480 | |||
2481 | 8 | $this->array = static::create($poppedValue)->array; |
|
2482 | } else { |
||
2483 | 4 | $number = (int)$number; |
|
2484 | 4 | $this->array = $this->rest(-$number)->array; |
|
2485 | } |
||
2486 | |||
2487 | 12 | return $this; |
|
2488 | } |
||
2489 | |||
2490 | /** |
||
2491 | * Count the values from the current array. |
||
2492 | * |
||
2493 | * alias: for "Arrayy->count()" |
||
2494 | * |
||
2495 | * @see Arrayy::count() |
||
2496 | * |
||
2497 | * @param int $mode |
||
2498 | * |
||
2499 | * @return int |
||
2500 | */ |
||
2501 | 20 | public function length(int $mode = COUNT_NORMAL): int |
|
2502 | { |
||
2503 | 20 | return $this->count($mode); |
|
2504 | } |
||
2505 | |||
2506 | /** |
||
2507 | * Apply the given function to the every element of the array, |
||
2508 | * collecting the results. |
||
2509 | * |
||
2510 | * @param \callable $callable |
||
2511 | * |
||
2512 | * @return static <p>(Immutable) Arrayy object with modified elements.</p> |
||
2513 | */ |
||
2514 | 4 | public function map($callable) |
|
2515 | { |
||
2516 | 4 | $result = \array_map($callable, $this->array); |
|
2517 | |||
2518 | 4 | return static::create($result); |
|
2519 | } |
||
2520 | |||
2521 | /** |
||
2522 | * Check if all items in current array match a truth test. |
||
2523 | * |
||
2524 | * @param \Closure $closure |
||
2525 | * |
||
2526 | * @return bool |
||
2527 | */ |
||
2528 | 15 | View Code Duplication | public function matches(\Closure $closure): bool |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2529 | { |
||
2530 | 15 | if (\count($this->array, COUNT_NORMAL) === 0) { |
|
2531 | 2 | return false; |
|
2532 | } |
||
2533 | |||
2534 | 13 | foreach ($this->getGenerator() as $key => $value) { |
|
2535 | 13 | $value = $closure($value, $key); |
|
2536 | |||
2537 | 13 | if ($value === false) { |
|
2538 | 13 | return false; |
|
2539 | } |
||
2540 | } |
||
2541 | |||
2542 | 7 | return true; |
|
2543 | } |
||
2544 | |||
2545 | /** |
||
2546 | * Check if any item in the current array matches a truth test. |
||
2547 | * |
||
2548 | * @param \Closure $closure |
||
2549 | * |
||
2550 | * @return bool |
||
2551 | */ |
||
2552 | 14 | View Code Duplication | public function matchesAny(\Closure $closure): bool |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2553 | { |
||
2554 | 14 | if (\count($this->array, COUNT_NORMAL) === 0) { |
|
2555 | 2 | return false; |
|
2556 | } |
||
2557 | |||
2558 | 12 | foreach ($this->getGenerator() as $key => $value) { |
|
2559 | 12 | $value = $closure($value, $key); |
|
2560 | |||
2561 | 12 | if ($value === true) { |
|
2562 | 12 | return true; |
|
2563 | } |
||
2564 | } |
||
2565 | |||
2566 | 4 | return false; |
|
2567 | } |
||
2568 | |||
2569 | /** |
||
2570 | * Get the max value from an array. |
||
2571 | * |
||
2572 | * @return mixed |
||
2573 | */ |
||
2574 | 10 | View Code Duplication | public function max() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2575 | { |
||
2576 | 10 | if (\count($this->array, COUNT_NORMAL) === 0) { |
|
2577 | 1 | return false; |
|
2578 | } |
||
2579 | |||
2580 | 9 | return max($this->array); |
|
2581 | } |
||
2582 | |||
2583 | /** |
||
2584 | * Merge the new $array into the current array. |
||
2585 | * |
||
2586 | * - keep key,value from the current array, also if the index is in the new $array |
||
2587 | * |
||
2588 | * @param array $array |
||
2589 | * @param bool $recursive |
||
2590 | * |
||
2591 | * @return static <p>(Immutable)</p> |
||
2592 | */ |
||
2593 | 25 | View Code Duplication | public function mergeAppendKeepIndex(array $array = [], bool $recursive = false) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2594 | { |
||
2595 | 25 | if (true === $recursive) { |
|
2596 | 4 | $result = \array_replace_recursive($this->array, $array); |
|
2597 | } else { |
||
2598 | 21 | $result = \array_replace($this->array, $array); |
|
2599 | } |
||
2600 | |||
2601 | 25 | return static::create($result); |
|
2602 | } |
||
2603 | |||
2604 | /** |
||
2605 | * Merge the new $array into the current array. |
||
2606 | * |
||
2607 | * - replace duplicate assoc-keys from the current array with the key,values from the new $array |
||
2608 | * - create new indexes |
||
2609 | * |
||
2610 | * @param array $array |
||
2611 | * @param bool $recursive |
||
2612 | * |
||
2613 | * @return static <p>(Immutable)</p> |
||
2614 | */ |
||
2615 | 16 | View Code Duplication | public function mergeAppendNewIndex(array $array = [], bool $recursive = false) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2616 | { |
||
2617 | 16 | if (true === $recursive) { |
|
2618 | 4 | $result = \array_merge_recursive($this->array, $array); |
|
2619 | } else { |
||
2620 | 12 | $result = \array_merge($this->array, $array); |
|
2621 | } |
||
2622 | |||
2623 | 16 | return static::create($result); |
|
2624 | } |
||
2625 | |||
2626 | /** |
||
2627 | * Merge the the current array into the $array. |
||
2628 | * |
||
2629 | * - use key,value from the new $array, also if the index is in the current array |
||
2630 | * |
||
2631 | * @param array $array |
||
2632 | * @param bool $recursive |
||
2633 | * |
||
2634 | * @return static <p>(Immutable)</p> |
||
2635 | */ |
||
2636 | 16 | View Code Duplication | public function mergePrependKeepIndex(array $array = [], bool $recursive = false) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2637 | { |
||
2638 | 16 | if (true === $recursive) { |
|
2639 | 4 | $result = \array_replace_recursive($array, $this->array); |
|
2640 | } else { |
||
2641 | 12 | $result = \array_replace($array, $this->array); |
|
2642 | } |
||
2643 | |||
2644 | 16 | return static::create($result); |
|
2645 | } |
||
2646 | |||
2647 | /** |
||
2648 | * Merge the current array into the new $array. |
||
2649 | * |
||
2650 | * - replace duplicate assoc-keys from new $array with the key,values from the current array |
||
2651 | * - create new indexes |
||
2652 | * |
||
2653 | * @param array $array |
||
2654 | * @param bool $recursive |
||
2655 | * |
||
2656 | * @return static <p>(Immutable)</p> |
||
2657 | */ |
||
2658 | 17 | View Code Duplication | public function mergePrependNewIndex(array $array = [], bool $recursive = false) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2659 | { |
||
2660 | 17 | if (true === $recursive) { |
|
2661 | 4 | $result = \array_merge_recursive($array, $this->array); |
|
2662 | } else { |
||
2663 | 13 | $result = \array_merge($array, $this->array); |
|
2664 | } |
||
2665 | |||
2666 | 17 | return static::create($result); |
|
2667 | } |
||
2668 | |||
2669 | /** |
||
2670 | * @return ArrayyMeta|static |
||
2671 | */ |
||
2672 | 7 | public static function meta() |
|
2673 | { |
||
2674 | 7 | return (new ArrayyMeta())->getMetaObject(static::class); |
|
2675 | } |
||
2676 | |||
2677 | /** |
||
2678 | * Get the min value from an array. |
||
2679 | * |
||
2680 | * @return mixed |
||
2681 | */ |
||
2682 | 10 | View Code Duplication | public function min() |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2683 | { |
||
2684 | 10 | if (\count($this->array, COUNT_NORMAL) === 0) { |
|
2685 | 1 | return false; |
|
2686 | } |
||
2687 | |||
2688 | 9 | return min($this->array); |
|
2689 | } |
||
2690 | |||
2691 | /** |
||
2692 | * Move an array element to a new index. |
||
2693 | * |
||
2694 | * cherry-picked from: http://stackoverflow.com/questions/12624153/move-an-array-element-to-a-new-index-in-php |
||
2695 | * |
||
2696 | * @param int|string $from |
||
2697 | * @param int|string $to |
||
2698 | * |
||
2699 | * @return static <p>(Immutable)</p> |
||
2700 | */ |
||
2701 | 1 | public function moveElement($from, $to) |
|
2702 | { |
||
2703 | 1 | $array = $this->array; |
|
2704 | |||
2705 | 1 | if (\is_int($from)) { |
|
2706 | 1 | $tmp = \array_splice($array, $from, 1); |
|
2707 | 1 | \array_splice($array, $to, 0, $tmp); |
|
2708 | 1 | $output = $array; |
|
2709 | 1 | } elseif (\is_string($from)) { |
|
2710 | 1 | $indexToMove = \array_search($from, \array_keys($array), true); |
|
2711 | 1 | $itemToMove = $array[$from]; |
|
2712 | 1 | \array_splice($array, $indexToMove, 1); |
|
2713 | 1 | $i = 0; |
|
2714 | 1 | $output = []; |
|
2715 | 1 | foreach ($array as $key => $item) { |
|
2716 | 1 | if ($i == $to) { |
|
2717 | 1 | $output[$from] = $itemToMove; |
|
2718 | } |
||
2719 | 1 | $output[$key] = $item; |
|
2720 | 1 | $i++; |
|
2721 | } |
||
2722 | } else { |
||
2723 | $output = []; |
||
2724 | } |
||
2725 | |||
2726 | 1 | return static::create($output); |
|
2727 | } |
||
2728 | |||
2729 | /** |
||
2730 | * Convert a object into an array. |
||
2731 | * |
||
2732 | * @param object $object |
||
2733 | * |
||
2734 | * @return mixed |
||
2735 | */ |
||
2736 | 5 | protected static function objectToArray($object) |
|
2737 | { |
||
2738 | 5 | if (!\is_object($object)) { |
|
2739 | 4 | return $object; |
|
2740 | } |
||
2741 | |||
2742 | 5 | if (\is_object($object)) { |
|
2743 | 5 | $object = \get_object_vars($object); |
|
2744 | } |
||
2745 | |||
2746 | 5 | return \array_map(['self', 'objectToArray'], $object); |
|
2747 | } |
||
2748 | |||
2749 | /** |
||
2750 | * Get a subset of the items from the given array. |
||
2751 | * |
||
2752 | * @param mixed[] $keys |
||
2753 | * |
||
2754 | * @return static <p>(Immutable)</p> |
||
2755 | */ |
||
2756 | public function only(array $keys) |
||
2757 | { |
||
2758 | $array = $this->array; |
||
2759 | |||
2760 | return static::create(\array_intersect_key($array, \array_flip($keys))); |
||
2761 | } |
||
2762 | |||
2763 | /** |
||
2764 | * Pad array to the specified size with a given value. |
||
2765 | * |
||
2766 | * @param int $size <p>Size of the result array.</p> |
||
2767 | * @param mixed $value <p>Empty value by default.</p> |
||
2768 | * |
||
2769 | * @return static <p>(Immutable) Arrayy object padded to $size with $value.</p> |
||
2770 | */ |
||
2771 | 4 | public function pad(int $size, $value) |
|
2772 | { |
||
2773 | 4 | $result = \array_pad($this->array, $size, $value); |
|
2774 | |||
2775 | 4 | return static::create($result); |
|
2776 | } |
||
2777 | |||
2778 | /** |
||
2779 | * Pop a specified value off the end of the current array. |
||
2780 | * |
||
2781 | * @return mixed <p>(Mutable) The popped element from the current array.</p> |
||
2782 | */ |
||
2783 | 16 | public function pop() |
|
2784 | { |
||
2785 | 16 | return \array_pop($this->array); |
|
2786 | } |
||
2787 | |||
2788 | /** |
||
2789 | * Prepend a (key) + value to the current array. |
||
2790 | * |
||
2791 | * @param mixed $value |
||
2792 | * @param mixed $key |
||
2793 | * |
||
2794 | * @return static <p>(Mutable) Return this Arrayy object, with the prepended value.</p> |
||
2795 | */ |
||
2796 | 8 | public function prepend($value, $key = null) |
|
2797 | { |
||
2798 | 8 | if ($key === null) { |
|
2799 | 8 | \array_unshift($this->array, $value); |
|
2800 | } else { |
||
2801 | /** @noinspection AdditionOperationOnArraysInspection */ |
||
2802 | 1 | $this->array = [$key => $value] + $this->array; |
|
2803 | } |
||
2804 | |||
2805 | 8 | return $this; |
|
2806 | } |
||
2807 | |||
2808 | /** |
||
2809 | * Add a suffix to each key. |
||
2810 | * |
||
2811 | * @param mixed $suffix |
||
2812 | * |
||
2813 | * @return static <p>(Immutable) Return an Arrayy object, with the prepended keys.</p> |
||
2814 | */ |
||
2815 | 10 | View Code Duplication | public function prependToEachKey($suffix) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2816 | { |
||
2817 | // init |
||
2818 | 10 | $result = []; |
|
2819 | |||
2820 | 10 | foreach ($this->getGenerator() as $key => $item) { |
|
2821 | 9 | if ($item instanceof self) { |
|
2822 | $result[$key] = $item->prependToEachKey($suffix); |
||
2823 | 9 | } elseif (\is_array($item)) { |
|
2824 | $result[$key] = self::create($item)->prependToEachKey($suffix)->toArray(); |
||
2825 | } else { |
||
2826 | 9 | $result[$key . $suffix] = $item; |
|
2827 | } |
||
2828 | |||
2829 | } |
||
2830 | |||
2831 | 10 | return self::create($result); |
|
2832 | } |
||
2833 | |||
2834 | /** |
||
2835 | * Add a suffix to each value. |
||
2836 | * |
||
2837 | * @param mixed $suffix |
||
2838 | * |
||
2839 | * @return static <p>(Immutable) Return an Arrayy object, with the prepended values.</p> |
||
2840 | */ |
||
2841 | 10 | View Code Duplication | public function prependToEachValue($suffix) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2842 | { |
||
2843 | // init |
||
2844 | 10 | $result = []; |
|
2845 | |||
2846 | 10 | foreach ($this->getGenerator() as $key => $item) { |
|
2847 | 9 | if ($item instanceof self) { |
|
2848 | $result[$key] = $item->prependToEachValue($suffix); |
||
2849 | 9 | } elseif (\is_array($item)) { |
|
2850 | $result[$key] = self::create($item)->prependToEachValue($suffix)->toArray(); |
||
2851 | 9 | } elseif (\is_object($item)) { |
|
2852 | 1 | $result[$key] = $item; |
|
2853 | } else { |
||
2854 | 9 | $result[$key] = $item . $suffix; |
|
2855 | } |
||
2856 | } |
||
2857 | |||
2858 | 10 | return self::create($result); |
|
2859 | } |
||
2860 | |||
2861 | /** |
||
2862 | * Push one or more values onto the end of array at once. |
||
2863 | * |
||
2864 | * @return static <p>(Mutable) Return this Arrayy object, with pushed elements to the end of array.</p> |
||
2865 | */ |
||
2866 | 4 | View Code Duplication | public function push(/* variadic arguments allowed */) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2867 | { |
||
2868 | 4 | if (\func_num_args()) { |
|
2869 | 4 | $args = \array_merge([&$this->array], \func_get_args()); |
|
2870 | 4 | \array_push(...$args); |
|
2871 | } |
||
2872 | |||
2873 | 4 | return $this; |
|
2874 | } |
||
2875 | |||
2876 | /** |
||
2877 | * Get a random value from the current array. |
||
2878 | * |
||
2879 | * @param null|int $number <p>How many values you will take?</p> |
||
2880 | * |
||
2881 | * @return static <p>(Immutable)</p> |
||
2882 | */ |
||
2883 | 18 | public function randomImmutable(int $number = null) |
|
2884 | { |
||
2885 | 18 | if (\count($this->array, COUNT_NORMAL) === 0) { |
|
2886 | 1 | return static::create(); |
|
2887 | } |
||
2888 | |||
2889 | 17 | View Code Duplication | if ($number === null) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2890 | /** @noinspection NonSecureArrayRandUsageInspection */ |
||
2891 | 14 | $arrayRandValue = [$this->array[\array_rand($this->array)]]; |
|
2892 | |||
2893 | 14 | return static::create($arrayRandValue); |
|
2894 | } |
||
2895 | |||
2896 | 5 | $arrayTmp = $this->array; |
|
2897 | /** @noinspection NonSecureShuffleUsageInspection */ |
||
2898 | 5 | \shuffle($arrayTmp); |
|
2899 | |||
2900 | 5 | return static::create($arrayTmp)->firstsImmutable($number); |
|
2901 | } |
||
2902 | |||
2903 | /** |
||
2904 | * Pick a random key/index from the keys of this array. |
||
2905 | * |
||
2906 | * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p> |
||
2907 | * |
||
2908 | * @throws \RangeException If array is empty |
||
2909 | */ |
||
2910 | 4 | public function randomKey() |
|
2911 | { |
||
2912 | 4 | $result = $this->randomKeys(1); |
|
2913 | |||
2914 | 4 | if (!isset($result[0])) { |
|
2915 | $result[0] = null; |
||
2916 | } |
||
2917 | |||
2918 | 4 | return $result[0]; |
|
2919 | } |
||
2920 | |||
2921 | /** |
||
2922 | * Pick a given number of random keys/indexes out of this array. |
||
2923 | * |
||
2924 | * @param int $number <p>The number of keys/indexes (should be <= \count($this->array))</p> |
||
2925 | * |
||
2926 | * @return static <p>(Immutable)</p> |
||
2927 | * |
||
2928 | * @throws \RangeException If array is empty |
||
2929 | */ |
||
2930 | 13 | public function randomKeys(int $number) |
|
2931 | { |
||
2932 | 13 | $count = \count($this->array, COUNT_NORMAL); |
|
2933 | |||
2934 | 13 | if ($number === 0 || $number > $count) { |
|
2935 | 2 | throw new \RangeException( |
|
2936 | 2 | \sprintf( |
|
2937 | 2 | 'Number of requested keys (%s) must be equal or lower than number of elements in this array (%s)', |
|
2938 | 2 | $number, |
|
2939 | 2 | $count |
|
2940 | ) |
||
2941 | ); |
||
2942 | } |
||
2943 | |||
2944 | 11 | $result = (array)\array_rand($this->array, $number); |
|
2945 | |||
2946 | 11 | return static::create($result); |
|
2947 | } |
||
2948 | |||
2949 | /** |
||
2950 | * Get a random value from the current array. |
||
2951 | * |
||
2952 | * @param null|int $number <p>How many values you will take?</p> |
||
2953 | * |
||
2954 | * @return static <p>(Mutable)</p> |
||
2955 | */ |
||
2956 | 17 | public function randomMutable(int $number = null) |
|
2957 | { |
||
2958 | 17 | if (\count($this->array, COUNT_NORMAL) === 0) { |
|
2959 | return static::create(); |
||
2960 | } |
||
2961 | |||
2962 | 17 | View Code Duplication | if ($number === null) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
2963 | /** @noinspection NonSecureArrayRandUsageInspection */ |
||
2964 | 7 | $arrayRandValue = [$this->array[\array_rand($this->array)]]; |
|
2965 | 7 | $this->array = $arrayRandValue; |
|
2966 | |||
2967 | 7 | return $this; |
|
2968 | } |
||
2969 | |||
2970 | /** @noinspection NonSecureShuffleUsageInspection */ |
||
2971 | 11 | \shuffle($this->array); |
|
2972 | |||
2973 | 11 | return $this->firstsMutable($number); |
|
2974 | } |
||
2975 | |||
2976 | /** |
||
2977 | * Pick a random value from the values of this array. |
||
2978 | * |
||
2979 | * @return mixed <p>Get a random value or null if there wasn't a value.</p> |
||
2980 | */ |
||
2981 | 4 | public function randomValue() |
|
2982 | { |
||
2983 | 4 | $result = $this->randomImmutable(); |
|
2984 | |||
2985 | 4 | if (!isset($result[0])) { |
|
2986 | $result[0] = null; |
||
2987 | } |
||
2988 | |||
2989 | 4 | return $result[0]; |
|
2990 | } |
||
2991 | |||
2992 | /** |
||
2993 | * Pick a given number of random values out of this array. |
||
2994 | * |
||
2995 | * @param int $number |
||
2996 | * |
||
2997 | * @return static <p>(Mutable)</p> |
||
2998 | */ |
||
2999 | 7 | public function randomValues(int $number) |
|
3000 | { |
||
3001 | 7 | return $this->randomMutable($number); |
|
3002 | } |
||
3003 | |||
3004 | /** |
||
3005 | * Get a random value from an array, with the ability to skew the results. |
||
3006 | * |
||
3007 | * Example: randomWeighted(['foo' => 1, 'bar' => 2]) has a 66% chance of returning bar. |
||
3008 | * |
||
3009 | * @param array $array |
||
3010 | * @param null|int $number <p>How many values you will take?</p> |
||
3011 | * |
||
3012 | * @return static <p>(Immutable)</p> |
||
3013 | */ |
||
3014 | 9 | public function randomWeighted(array $array, int $number = null) |
|
3015 | { |
||
3016 | // init |
||
3017 | 9 | $options = []; |
|
3018 | |||
3019 | 9 | foreach ($array as $option => $weight) { |
|
3020 | 9 | if ($this->searchIndex($option) !== false) { |
|
3021 | 9 | for ($i = 0; $i < $weight; ++$i) { |
|
3022 | 1 | $options[] = $option; |
|
3023 | } |
||
3024 | } |
||
3025 | } |
||
3026 | |||
3027 | 9 | return $this->mergeAppendKeepIndex($options)->randomImmutable($number); |
|
3028 | } |
||
3029 | |||
3030 | /** |
||
3031 | * Reduce the current array via callable e.g. anonymous-function. |
||
3032 | * |
||
3033 | * @param \callable $callable |
||
3034 | * @param array $init |
||
3035 | * |
||
3036 | * @return static <p>(Immutable)</p> |
||
3037 | */ |
||
3038 | 4 | public function reduce($callable, array $init = []) |
|
3039 | { |
||
3040 | 4 | $result = \array_reduce($this->array, $callable, $init); |
|
3041 | |||
3042 | 4 | if ($result === null) { |
|
3043 | $this->array = []; |
||
3044 | } else { |
||
3045 | 4 | $this->array = (array)$result; |
|
3046 | } |
||
3047 | |||
3048 | 4 | return static::create($this->array); |
|
3049 | } |
||
3050 | |||
3051 | /** |
||
3052 | * Create a numerically re-indexed Arrayy object. |
||
3053 | * |
||
3054 | * @return static <p>(Mutable) Return this Arrayy object, with re-indexed array-elements.</p> |
||
3055 | */ |
||
3056 | 9 | public function reindex() |
|
3057 | { |
||
3058 | 9 | $this->array = \array_values($this->array); |
|
3059 | |||
3060 | 9 | return $this; |
|
3061 | } |
||
3062 | |||
3063 | /** |
||
3064 | * Return all items that fail the truth test. |
||
3065 | * |
||
3066 | * @param \Closure $closure |
||
3067 | * |
||
3068 | * @return static <p>(Immutable)</p> |
||
3069 | */ |
||
3070 | 1 | View Code Duplication | public function reject(\Closure $closure) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
3071 | { |
||
3072 | 1 | $filtered = []; |
|
3073 | |||
3074 | 1 | foreach ($this->getGenerator() as $key => $value) { |
|
3075 | 1 | if (!$closure($value, $key)) { |
|
3076 | 1 | $filtered[$key] = $value; |
|
3077 | } |
||
3078 | } |
||
3079 | |||
3080 | 1 | return static::create($filtered); |
|
3081 | } |
||
3082 | |||
3083 | /** |
||
3084 | * Remove a value from the current array (optional using dot-notation). |
||
3085 | * |
||
3086 | * @param mixed $key |
||
3087 | * |
||
3088 | * @return static <p>(Immutable)</p> |
||
3089 | */ |
||
3090 | 18 | public function remove($key) |
|
3091 | { |
||
3092 | // recursive call |
||
3093 | 18 | if (\is_array($key)) { |
|
3094 | foreach ($key as $k) { |
||
3095 | $this->internalRemove($k); |
||
3096 | } |
||
3097 | |||
3098 | return static::create($this->array); |
||
3099 | } |
||
3100 | |||
3101 | 18 | $this->internalRemove($key); |
|
3102 | |||
3103 | 18 | return static::create($this->array); |
|
3104 | } |
||
3105 | |||
3106 | /** |
||
3107 | * Remove the first value from the current array. |
||
3108 | * |
||
3109 | * @return static <p>(Immutable)</p> |
||
3110 | */ |
||
3111 | 7 | public function removeFirst() |
|
3112 | { |
||
3113 | 7 | $tmpArray = $this->array; |
|
3114 | 7 | \array_shift($tmpArray); |
|
3115 | |||
3116 | 7 | return static::create($tmpArray); |
|
3117 | } |
||
3118 | |||
3119 | /** |
||
3120 | * Remove the last value from the current array. |
||
3121 | * |
||
3122 | * @return static <p>(Immutable)</p> |
||
3123 | */ |
||
3124 | 7 | public function removeLast() |
|
3125 | { |
||
3126 | 7 | $tmpArray = $this->array; |
|
3127 | 7 | \array_pop($tmpArray); |
|
3128 | |||
3129 | 7 | return static::create($tmpArray); |
|
3130 | } |
||
3131 | |||
3132 | /** |
||
3133 | * Removes a particular value from an array (numeric or associative). |
||
3134 | * |
||
3135 | * @param mixed $value |
||
3136 | * |
||
3137 | * @return static <p>(Immutable)</p> |
||
3138 | */ |
||
3139 | 7 | public function removeValue($value) |
|
3140 | { |
||
3141 | 7 | $isNumericArray = true; |
|
3142 | 7 | foreach ($this->getGenerator() as $key => $item) { |
|
3143 | 6 | if ($item === $value) { |
|
3144 | 6 | if (!\is_int($key)) { |
|
3145 | $isNumericArray = false; |
||
3146 | } |
||
3147 | 6 | unset($this->array[$key]); |
|
3148 | } |
||
3149 | } |
||
3150 | |||
3151 | 7 | if ($isNumericArray) { |
|
3152 | 7 | $this->array = \array_values($this->array); |
|
3153 | } |
||
3154 | |||
3155 | 7 | return static::create($this->array); |
|
3156 | } |
||
3157 | |||
3158 | /** |
||
3159 | * Generate array of repeated arrays. |
||
3160 | * |
||
3161 | * @param int $times <p>How many times has to be repeated.</p> |
||
3162 | * |
||
3163 | * @return Arrayy |
||
3164 | */ |
||
3165 | 1 | public function repeat($times): self |
|
3166 | { |
||
3167 | 1 | if ($times === 0) { |
|
3168 | 1 | return new static(); |
|
3169 | } |
||
3170 | |||
3171 | 1 | return static::create(\array_fill(0, (int)$times, $this->array)); |
|
3172 | } |
||
3173 | |||
3174 | /** |
||
3175 | * Replace a key with a new key/value pair. |
||
3176 | * |
||
3177 | * @param mixed $replace |
||
3178 | * @param mixed $key |
||
3179 | * @param mixed $value |
||
3180 | * |
||
3181 | * @return static <p>(Immutable)</p> |
||
3182 | */ |
||
3183 | 2 | public function replace($replace, $key, $value) |
|
3184 | { |
||
3185 | 2 | $that = $this->remove($replace); |
|
3186 | |||
3187 | 2 | return $that->set($key, $value); |
|
3188 | } |
||
3189 | |||
3190 | /** |
||
3191 | * Create an array using the current array as values and the other array as keys. |
||
3192 | * |
||
3193 | * @param array $keys <p>An array of keys.</p> |
||
3194 | * |
||
3195 | * @return static <p>(Immutable) Arrayy object with keys from the other array.</p> |
||
3196 | */ |
||
3197 | 2 | public function replaceAllKeys(array $keys) |
|
3198 | { |
||
3199 | 2 | $result = \array_combine($keys, $this->array); |
|
3200 | |||
3201 | 2 | return static::create($result); |
|
3202 | } |
||
3203 | |||
3204 | /** |
||
3205 | * Create an array using the current array as keys and the other array as values. |
||
3206 | * |
||
3207 | * @param array $array <p>An array o values.</p> |
||
3208 | * |
||
3209 | * @return static <p>(Immutable) Arrayy object with values from the other array.</p> |
||
3210 | */ |
||
3211 | 2 | public function replaceAllValues(array $array) |
|
3212 | { |
||
3213 | 2 | $result = \array_combine($this->array, $array); |
|
3214 | |||
3215 | 2 | return static::create($result); |
|
3216 | } |
||
3217 | |||
3218 | /** |
||
3219 | * Replace the keys in an array with another set. |
||
3220 | * |
||
3221 | * @param array $keys <p>An array of keys matching the array's size</p> |
||
3222 | * |
||
3223 | * @return static <p>(Immutable)</p> |
||
3224 | */ |
||
3225 | 1 | public function replaceKeys(array $keys) |
|
3226 | { |
||
3227 | 1 | $values = \array_values($this->array); |
|
3228 | 1 | $result = \array_combine($keys, $values); |
|
3229 | |||
3230 | 1 | return static::create($result); |
|
3231 | } |
||
3232 | |||
3233 | /** |
||
3234 | * Replace the first matched value in an array. |
||
3235 | * |
||
3236 | * @param mixed $search <p>The value to replace.</p> |
||
3237 | * @param mixed $replacement <p>The value to replace.</p> |
||
3238 | * |
||
3239 | * @return static <p>(Immutable)</p> |
||
3240 | */ |
||
3241 | 3 | public function replaceOneValue($search, $replacement = '') |
|
3242 | { |
||
3243 | 3 | $array = $this->array; |
|
3244 | 3 | $key = \array_search($search, $array, true); |
|
3245 | |||
3246 | 3 | if ($key !== false) { |
|
3247 | 3 | $array[$key] = $replacement; |
|
3248 | } |
||
3249 | |||
3250 | 3 | return static::create($array); |
|
3251 | } |
||
3252 | |||
3253 | /** |
||
3254 | * Replace values in the current array. |
||
3255 | * |
||
3256 | * @param mixed $search <p>The value to replace.</p> |
||
3257 | * @param mixed $replacement <p>What to replace it with.</p> |
||
3258 | * |
||
3259 | * @return static <p>(Immutable)</p> |
||
3260 | */ |
||
3261 | 1 | public function replaceValues($search, $replacement = '') |
|
3262 | { |
||
3263 | 1 | $array = $this->each( |
|
3264 | 1 | function ($value) use ($search, $replacement) { |
|
3265 | 1 | return UTF8::str_replace($search, $replacement, $value); |
|
3266 | 1 | } |
|
3267 | ); |
||
3268 | |||
3269 | 1 | return $array; |
|
3270 | } |
||
3271 | |||
3272 | /** |
||
3273 | * Get the last elements from index $from until the end of this array. |
||
3274 | * |
||
3275 | * @param int $from |
||
3276 | * |
||
3277 | * @return static <p>(Immutable)</p> |
||
3278 | */ |
||
3279 | 15 | public function rest(int $from = 1) |
|
3280 | { |
||
3281 | 15 | $tmpArray = $this->array; |
|
3282 | |||
3283 | 15 | return static::create(\array_splice($tmpArray, $from)); |
|
3284 | } |
||
3285 | |||
3286 | /** |
||
3287 | * Return the array in the reverse order. |
||
3288 | * |
||
3289 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
3290 | */ |
||
3291 | 8 | public function reverse() |
|
3292 | { |
||
3293 | 8 | $this->array = \array_reverse($this->array); |
|
3294 | |||
3295 | 8 | return $this; |
|
3296 | } |
||
3297 | |||
3298 | /** |
||
3299 | * Sort an array in reverse order. |
||
3300 | * |
||
3301 | * @param int $sort_flags [optional] <p> |
||
3302 | * You may modify the behavior of the sort using the optional |
||
3303 | * parameter sort_flags, for details |
||
3304 | * see sort. |
||
3305 | * </p> |
||
3306 | * |
||
3307 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
3308 | */ |
||
3309 | 4 | public function rsort(int $sort_flags = 0) |
|
3310 | { |
||
3311 | 4 | \rsort($this->array, $sort_flags); |
|
3312 | |||
3313 | 4 | return $this; |
|
3314 | } |
||
3315 | |||
3316 | /** |
||
3317 | * Search for the first index of the current array via $value. |
||
3318 | * |
||
3319 | * @param mixed $value |
||
3320 | * |
||
3321 | * @return int|float|string |
||
3322 | */ |
||
3323 | 20 | public function searchIndex($value) |
|
3324 | { |
||
3325 | 20 | return \array_search($value, $this->array, true); |
|
3326 | } |
||
3327 | |||
3328 | /** |
||
3329 | * Search for the value of the current array via $index. |
||
3330 | * |
||
3331 | * @param mixed $index |
||
3332 | * |
||
3333 | * @return static <p>(Immutable) Will return a empty Arrayy if the value wasn't found.</p> |
||
3334 | */ |
||
3335 | 9 | public function searchValue($index) |
|
3336 | { |
||
3337 | // init |
||
3338 | 9 | $return = []; |
|
3339 | |||
3340 | 9 | if ($this->isEmpty()) { |
|
3341 | return static::create(); |
||
3342 | } |
||
3343 | |||
3344 | // php cast "bool"-index into "int"-index |
||
3345 | 9 | if ((bool)$index === $index) { |
|
3346 | 1 | $index = (int)$index; |
|
3347 | } |
||
3348 | |||
3349 | 9 | if (\array_key_exists($index, $this->array) === true) { |
|
3350 | 7 | $return = [$this->array[$index]]; |
|
3351 | } |
||
3352 | |||
3353 | |||
3354 | 9 | return static::create($return); |
|
3355 | } |
||
3356 | |||
3357 | /** |
||
3358 | * Set a value for the current array (optional using dot-notation). |
||
3359 | * |
||
3360 | * @param string $key <p>The key to set.</p> |
||
3361 | * @param mixed $value <p>Its value.</p> |
||
3362 | * |
||
3363 | * @return static <p>(Immutable)</p> |
||
3364 | */ |
||
3365 | 17 | public function set($key, $value) |
|
3366 | { |
||
3367 | 17 | $this->internalSet($key, $value); |
|
3368 | |||
3369 | 17 | return static::create($this->array); |
|
3370 | } |
||
3371 | |||
3372 | /** |
||
3373 | * Get a value from a array and set it if it was not. |
||
3374 | * |
||
3375 | * WARNING: this method only set the value, if the $key is not already set |
||
3376 | * |
||
3377 | * @param mixed $key <p>The key</p> |
||
3378 | * @param mixed $fallback <p>The default value to set if it isn't.</p> |
||
3379 | * |
||
3380 | * @return mixed <p>(Mutable)</p> |
||
3381 | */ |
||
3382 | 11 | public function setAndGet($key, $fallback = null) |
|
3383 | { |
||
3384 | // If the key doesn't exist, set it. |
||
3385 | 11 | if (!$this->has($key)) { |
|
3386 | 4 | $this->array = $this->set($key, $fallback)->getArray(); |
|
3387 | } |
||
3388 | |||
3389 | 11 | return $this->get($key); |
|
3390 | } |
||
3391 | |||
3392 | /** |
||
3393 | * Shifts a specified value off the beginning of array. |
||
3394 | * |
||
3395 | * @return mixed <p>(Mutable) A shifted element from the current array.</p> |
||
3396 | */ |
||
3397 | 4 | public function shift() |
|
3398 | { |
||
3399 | 4 | return \array_shift($this->array); |
|
3400 | } |
||
3401 | |||
3402 | /** |
||
3403 | * Shuffle the current array. |
||
3404 | * |
||
3405 | * @param bool $secure <p>using a CSPRNG | @link https://paragonie.com/b/JvICXzh_jhLyt4y3</p> |
||
3406 | * @param array $array [optional] |
||
3407 | * |
||
3408 | * @return static <p>(Immutable)</p> |
||
3409 | */ |
||
3410 | 1 | public function shuffle(bool $secure = false, array $array = null) |
|
3411 | { |
||
3412 | 1 | if ($array === null) { |
|
3413 | 1 | $array = $this->array; |
|
3414 | } |
||
3415 | |||
3416 | 1 | if ($secure !== true) { |
|
3417 | /** @noinspection NonSecureShuffleUsageInspection */ |
||
3418 | 1 | \shuffle($array); |
|
3419 | } else { |
||
3420 | 1 | $size = \count($array, COUNT_NORMAL); |
|
3421 | 1 | $keys = \array_keys($array); |
|
3422 | 1 | for ($i = $size - 1; $i > 0; --$i) { |
|
3423 | try { |
||
3424 | 1 | $r = \random_int(0, $i); |
|
3425 | } catch (\Exception $e) { |
||
3426 | $r = \mt_rand(); |
||
3427 | } |
||
3428 | 1 | if ($r !== $i) { |
|
3429 | 1 | $temp = $array[$keys[$r]]; |
|
3430 | 1 | $array[$keys[$r]] = $array[$keys[$i]]; |
|
3431 | 1 | $array[$keys[$i]] = $temp; |
|
3432 | } |
||
3433 | } |
||
3434 | |||
3435 | // reset indices |
||
3436 | 1 | $array = \array_values($array); |
|
3437 | } |
||
3438 | |||
3439 | 1 | foreach ($array as $key => $value) { |
|
3440 | // check if recursive is needed |
||
3441 | 1 | if (\is_array($value) === true) { |
|
3442 | 1 | $array[$key] = $this->shuffle($secure, $value); |
|
3443 | } |
||
3444 | } |
||
3445 | |||
3446 | 1 | return static::create($array); |
|
3447 | } |
||
3448 | |||
3449 | /** |
||
3450 | * Count the values from the current array. |
||
3451 | * |
||
3452 | * alias: for "Arrayy->count()" |
||
3453 | * |
||
3454 | * @param int $mode |
||
3455 | * |
||
3456 | * @return int |
||
3457 | */ |
||
3458 | 20 | public function size(int $mode = COUNT_NORMAL): int |
|
3459 | { |
||
3460 | 20 | return $this->count($mode); |
|
3461 | } |
||
3462 | |||
3463 | /** |
||
3464 | * Counts all elements in an array, or something in an object. |
||
3465 | * <p>For objects, if you have SPL installed, you can hook into count() by implementing interface {@see Countable}. |
||
3466 | * The interface has exactly one method, {@see Countable::count()}, which returns the return value for the count() |
||
3467 | * function. Please see the {@see Array} section of the manual for a detailed explanation of how arrays are |
||
3468 | * implemented and used in PHP. |
||
3469 | * |
||
3470 | * @return int the number of elements in var, which is |
||
3471 | * typically an array, since anything else will have one |
||
3472 | * element. |
||
3473 | * </p> |
||
3474 | * <p> |
||
3475 | * If var is not an array or an object with |
||
3476 | * implemented Countable interface, |
||
3477 | * 1 will be returned. |
||
3478 | * There is one exception, if var is &null;, |
||
3479 | * 0 will be returned. |
||
3480 | * </p> |
||
3481 | * <p> |
||
3482 | * Caution: count may return 0 for a variable that isn't set, |
||
3483 | * but it may also return 0 for a variable that has been initialized with an |
||
3484 | * empty array. Use isset to test if a variable is set. |
||
3485 | * |
||
3486 | * @return int |
||
3487 | */ |
||
3488 | 10 | public function sizeRecursive(): int |
|
3489 | { |
||
3490 | 10 | return \count($this->array, COUNT_RECURSIVE); |
|
3491 | } |
||
3492 | |||
3493 | /** |
||
3494 | * Extract a slice of the array. |
||
3495 | * |
||
3496 | * @param int $offset <p>Slice begin index.</p> |
||
3497 | * @param int|null $length <p>Length of the slice.</p> |
||
3498 | * @param bool $preserveKeys <p>Whether array keys are preserved or no.</p> |
||
3499 | * |
||
3500 | * @return static <p>A slice of the original array with length $length.</p> |
||
3501 | */ |
||
3502 | 4 | public function slice(int $offset, int $length = null, bool $preserveKeys = false) |
|
3503 | { |
||
3504 | 4 | $result = \array_slice($this->array, $offset, $length, $preserveKeys); |
|
3505 | |||
3506 | 4 | return static::create($result); |
|
3507 | } |
||
3508 | |||
3509 | /** |
||
3510 | * Sort the current array and optional you can keep the keys. |
||
3511 | * |
||
3512 | * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3513 | * @param int $strategy <p>sort_flags => use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3514 | * <strong>SORT_NATURAL</strong></p> |
||
3515 | * @param bool $keepKeys |
||
3516 | * |
||
3517 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
3518 | */ |
||
3519 | 19 | public function sort($direction = SORT_ASC, int $strategy = SORT_REGULAR, bool $keepKeys = false) |
|
3520 | { |
||
3521 | 19 | return $this->sorting($this->array, $direction, $strategy, $keepKeys); |
|
3522 | } |
||
3523 | |||
3524 | /** |
||
3525 | * Sort the current array by key. |
||
3526 | * |
||
3527 | * @link http://php.net/manual/en/function.ksort.php |
||
3528 | * @link http://php.net/manual/en/function.krsort.php |
||
3529 | * |
||
3530 | * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3531 | * @param int $strategy <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3532 | * <strong>SORT_NATURAL</strong></p> |
||
3533 | * |
||
3534 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
3535 | */ |
||
3536 | 18 | public function sortKeys($direction = SORT_ASC, int $strategy = SORT_REGULAR) |
|
3537 | { |
||
3538 | /** @noinspection UnusedFunctionResultInspection */ |
||
3539 | 18 | $this->sorterKeys($this->array, $direction, $strategy); |
|
3540 | |||
3541 | 18 | return $this; |
|
3542 | } |
||
3543 | |||
3544 | /** |
||
3545 | * Sort the current array by value. |
||
3546 | * |
||
3547 | * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3548 | * @param int $strategy <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3549 | * <strong>SORT_NATURAL</strong></p> |
||
3550 | * |
||
3551 | * @return static <p>(Mutable)</p> |
||
3552 | */ |
||
3553 | 1 | public function sortValueKeepIndex($direction = SORT_ASC, int $strategy = SORT_REGULAR) |
|
3554 | { |
||
3555 | 1 | return $this->sort($direction, $strategy, true); |
|
3556 | } |
||
3557 | |||
3558 | /** |
||
3559 | * Sort the current array by value. |
||
3560 | * |
||
3561 | * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3562 | * @param int $strategy <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3563 | * <strong>SORT_NATURAL</strong></p> |
||
3564 | * |
||
3565 | * @return static <p>(Mutable)</p> |
||
3566 | */ |
||
3567 | 1 | public function sortValueNewIndex($direction = SORT_ASC, int $strategy = SORT_REGULAR) |
|
3568 | { |
||
3569 | 1 | return $this->sort($direction, $strategy, false); |
|
3570 | } |
||
3571 | |||
3572 | /** |
||
3573 | * Sort a array by value, by a closure or by a property. |
||
3574 | * |
||
3575 | * - If the sorter is null, the array is sorted naturally. |
||
3576 | * - Associative (string) keys will be maintained, but numeric keys will be re-indexed. |
||
3577 | * |
||
3578 | * @param \callable|null $sorter |
||
3579 | * @param string|int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3580 | * @param int $strategy <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3581 | * <strong>SORT_NATURAL</strong></p> |
||
3582 | * |
||
3583 | * @return static <p>(Immutable)</p> |
||
3584 | */ |
||
3585 | 1 | public function sorter($sorter = null, $direction = SORT_ASC, int $strategy = SORT_REGULAR) |
|
3586 | { |
||
3587 | 1 | $array = (array)$this->array; |
|
3588 | 1 | $direction = $this->getDirection($direction); |
|
3589 | |||
3590 | // Transform all values into their results. |
||
3591 | 1 | if ($sorter) { |
|
3592 | 1 | $arrayy = static::create($array); |
|
3593 | |||
3594 | 1 | $that = $this; |
|
3595 | 1 | $results = $arrayy->each( |
|
3596 | 1 | function ($value) use ($sorter, $that) { |
|
3597 | 1 | return \is_callable($sorter) ? $sorter($value) : $that->get($sorter, null, $value); |
|
3598 | 1 | } |
|
3599 | ); |
||
3600 | |||
3601 | 1 | $results = $results->getArray(); |
|
3602 | } else { |
||
3603 | 1 | $results = $array; |
|
3604 | } |
||
3605 | |||
3606 | // Sort by the results and replace by original values |
||
3607 | 1 | \array_multisort($results, $direction, $strategy, $array); |
|
3608 | |||
3609 | 1 | return static::create($array); |
|
3610 | } |
||
3611 | |||
3612 | /** |
||
3613 | * sorting keys |
||
3614 | * |
||
3615 | * @param array $elements |
||
3616 | * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3617 | * @param int $strategy <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3618 | * <strong>SORT_NATURAL</strong></p> |
||
3619 | * |
||
3620 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
3621 | */ |
||
3622 | 18 | protected function sorterKeys(array &$elements, $direction = SORT_ASC, int $strategy = SORT_REGULAR) |
|
3623 | { |
||
3624 | 18 | $direction = $this->getDirection($direction); |
|
3625 | |||
3626 | switch ($direction) { |
||
3627 | 18 | case 'desc': |
|
3628 | 18 | case SORT_DESC: |
|
3629 | 6 | \krsort($elements, $strategy); |
|
3630 | 6 | break; |
|
3631 | 13 | case 'asc': |
|
3632 | 13 | case SORT_ASC: |
|
3633 | default: |
||
3634 | 13 | \ksort($elements, $strategy); |
|
3635 | } |
||
3636 | |||
3637 | 18 | return $this; |
|
3638 | } |
||
3639 | |||
3640 | /** |
||
3641 | * @param array &$elements |
||
3642 | * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p> |
||
3643 | * @param int $strategy <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or |
||
3644 | * <strong>SORT_NATURAL</strong></p> |
||
3645 | * @param bool $keepKeys |
||
3646 | * |
||
3647 | * @return static <p>(Mutable) Return this Arrayy object.</p> |
||
3648 | */ |
||
3649 | 19 | protected function sorting(array &$elements, $direction = SORT_ASC, int $strategy = SORT_REGULAR, bool $keepKeys = false) |
|
3650 | { |
||
3651 | 19 | $direction = $this->getDirection($direction); |
|
3652 | |||
3653 | 19 | if (!$strategy) { |
|
3654 | 19 | $strategy = SORT_REGULAR; |
|
3655 | } |
||
3656 | |||
3657 | switch ($direction) { |
||
3658 | 19 | case 'desc': |
|
3659 | 19 | case SORT_DESC: |
|
3660 | 9 | if ($keepKeys) { |
|
3661 | 5 | \arsort($elements, $strategy); |
|
3662 | } else { |
||
3663 | 4 | \rsort($elements, $strategy); |
|
3664 | } |
||
3665 | 9 | break; |
|
3666 | 10 | case 'asc': |
|
3667 | 10 | case SORT_ASC: |
|
3668 | default: |
||
3669 | 10 | if ($keepKeys) { |
|
3670 | 4 | \asort($elements, $strategy); |
|
3671 | } else { |
||
3672 | 6 | \sort($elements, $strategy); |
|
3673 | } |
||
3674 | } |
||
3675 | |||
3676 | 19 | return $this; |
|
3677 | } |
||
3678 | |||
3679 | /** |
||
3680 | * Split an array in the given amount of pieces. |
||
3681 | * |
||
3682 | * @param int $numberOfPieces |
||
3683 | * @param bool $keepKeys |
||
3684 | * |
||
3685 | * @return static <p>(Immutable)</p> |
||
3686 | */ |
||
3687 | 1 | public function split(int $numberOfPieces = 2, bool $keepKeys = false) |
|
3688 | { |
||
3689 | 1 | $arrayCount = \count($this->array, COUNT_NORMAL); |
|
3690 | |||
3691 | 1 | if ($arrayCount === 0) { |
|
3692 | 1 | $result = []; |
|
3693 | } else { |
||
3694 | 1 | $splitSize = (int)\ceil($arrayCount / $numberOfPieces); |
|
3695 | 1 | $result = \array_chunk($this->array, $splitSize, $keepKeys); |
|
3696 | } |
||
3697 | |||
3698 | 1 | return static::create($result); |
|
3699 | } |
||
3700 | |||
3701 | /** |
||
3702 | * Stripe all empty items. |
||
3703 | * |
||
3704 | * @return static <p>(Immutable)</p> |
||
3705 | */ |
||
3706 | 1 | public function stripEmpty() |
|
3707 | { |
||
3708 | 1 | return $this->filter( |
|
3709 | 1 | function ($item) { |
|
3710 | 1 | if ($item === null) { |
|
3711 | 1 | return false; |
|
3712 | } |
||
3713 | |||
3714 | 1 | return (bool)\trim((string)$item); |
|
3715 | 1 | } |
|
3716 | ); |
||
3717 | } |
||
3718 | |||
3719 | /** |
||
3720 | * Swap two values between positions by key. |
||
3721 | * |
||
3722 | * @param string|int $swapA <p>a key in the array</p> |
||
3723 | * @param string|int $swapB <p>a key in the array</p> |
||
3724 | * |
||
3725 | * @return static <p>(Immutable)</p> |
||
3726 | */ |
||
3727 | 1 | public function swap($swapA, $swapB) |
|
3728 | { |
||
3729 | 1 | $array = $this->array; |
|
3730 | |||
3731 | 1 | list($array[$swapA], $array[$swapB]) = [$array[$swapB], $array[$swapA]]; |
|
3732 | |||
3733 | 1 | return static::create($array); |
|
3734 | } |
||
3735 | |||
3736 | /** |
||
3737 | * alias: for "Arrayy->getArray()" |
||
3738 | * |
||
3739 | * @see Arrayy::getArray() |
||
3740 | */ |
||
3741 | 192 | public function toArray() |
|
3742 | { |
||
3743 | 192 | return $this->getArray(); |
|
3744 | } |
||
3745 | |||
3746 | /** |
||
3747 | * Convert the current array to JSON. |
||
3748 | * |
||
3749 | * @param int $options [optional] <p>e.g. JSON_PRETTY_PRINT</p> |
||
3750 | * @param int $depth [optional] <p>Set the maximum depth. Must be greater than zero.</p> |
||
3751 | * |
||
3752 | * @return string |
||
3753 | */ |
||
3754 | 6 | public function toJson(int $options = 0, int $depth = 512): string |
|
3755 | { |
||
3756 | 6 | return UTF8::json_encode($this->array, $options, $depth); |
|
3757 | } |
||
3758 | |||
3759 | /** |
||
3760 | * Implodes array to a string with specified separator. |
||
3761 | * |
||
3762 | * @param string $separator [optional] <p>The element's separator.</p> |
||
3763 | * |
||
3764 | * @return string <p>The string representation of array, separated by ",".</p> |
||
3765 | */ |
||
3766 | 19 | public function toString(string $separator = ','): string |
|
3767 | { |
||
3768 | 19 | return $this->implode($separator); |
|
3769 | } |
||
3770 | |||
3771 | /** |
||
3772 | * Return a duplicate free copy of the current array. |
||
3773 | * |
||
3774 | * @return static <p>(Mutable)</p> |
||
3775 | */ |
||
3776 | 10 | public function unique() |
|
3777 | { |
||
3778 | // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array |
||
3779 | |||
3780 | 10 | $this->array = \array_reduce( |
|
0 ignored issues
–
show
It seems like
\array_reduce($this->arr...esultArray; }, array()) of type * is incompatible with the declared type array of property $array .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..
Loading history...
|
|||
3781 | 10 | $this->array, |
|
3782 | 10 | function ($resultArray, $value) { |
|
3783 | 9 | if (!\in_array($value, $resultArray, true)) { |
|
3784 | 9 | $resultArray[] = $value; |
|
3785 | } |
||
3786 | |||
3787 | 9 | return $resultArray; |
|
3788 | 10 | }, |
|
3789 | 10 | [] |
|
3790 | ); |
||
3791 | |||
3792 | 10 | View Code Duplication | if ($this->array === null) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
3793 | $this->array = []; |
||
3794 | } else { |
||
3795 | 10 | $this->array = (array)$this->array; |
|
3796 | } |
||
3797 | |||
3798 | 10 | return $this; |
|
3799 | } |
||
3800 | |||
3801 | /** |
||
3802 | * Return a duplicate free copy of the current array. (with the old keys) |
||
3803 | * |
||
3804 | * @return static <p>(Mutable)</p> |
||
3805 | */ |
||
3806 | 11 | public function uniqueKeepIndex() |
|
3807 | { |
||
3808 | // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array |
||
3809 | |||
3810 | // init |
||
3811 | 11 | $array = $this->array; |
|
3812 | |||
3813 | 11 | $this->array = \array_reduce( |
|
0 ignored issues
–
show
It seems like
\array_reduce(\array_key...esultArray; }, array()) of type * is incompatible with the declared type array of property $array .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..
Loading history...
|
|||
3814 | 11 | \array_keys($array), |
|
3815 | 11 | function ($resultArray, $key) use ($array) { |
|
3816 | 10 | if (!\in_array($array[$key], $resultArray, true)) { |
|
3817 | 10 | $resultArray[$key] = $array[$key]; |
|
3818 | } |
||
3819 | |||
3820 | 10 | return $resultArray; |
|
3821 | 11 | }, |
|
3822 | 11 | [] |
|
3823 | ); |
||
3824 | |||
3825 | 11 | View Code Duplication | if ($this->array === null) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
3826 | $this->array = []; |
||
3827 | } else { |
||
3828 | 11 | $this->array = (array)$this->array; |
|
3829 | } |
||
3830 | |||
3831 | 11 | return $this; |
|
3832 | } |
||
3833 | |||
3834 | /** |
||
3835 | * alias: for "Arrayy->unique()" |
||
3836 | * |
||
3837 | * @see Arrayy::unique() |
||
3838 | * |
||
3839 | * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p> |
||
3840 | */ |
||
3841 | 10 | public function uniqueNewIndex() |
|
3842 | { |
||
3843 | 10 | return $this->unique(); |
|
3844 | } |
||
3845 | |||
3846 | /** |
||
3847 | * Prepends one or more values to the beginning of array at once. |
||
3848 | * |
||
3849 | * @return static <p>(Mutable) Return this Arrayy object, with prepended elements to the beginning of array.</p> |
||
3850 | */ |
||
3851 | 4 | View Code Duplication | public function unshift(/* variadic arguments allowed */) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
3852 | { |
||
3853 | 4 | if (\func_num_args()) { |
|
3854 | 4 | $args = \array_merge([&$this->array], \func_get_args()); |
|
3855 | 4 | \array_unshift(...$args); |
|
3856 | } |
||
3857 | |||
3858 | 4 | return $this; |
|
3859 | } |
||
3860 | |||
3861 | /** |
||
3862 | * Get all values from a array. |
||
3863 | * |
||
3864 | * @return static <p>(Immutable)</p> |
||
3865 | */ |
||
3866 | 2 | public function values() |
|
3867 | { |
||
3868 | 2 | return static::create(\array_values((array)$this->array)); |
|
3869 | } |
||
3870 | |||
3871 | /** |
||
3872 | * Apply the given function to every element in the array, discarding the results. |
||
3873 | * |
||
3874 | * @param \callable $callable |
||
3875 | * @param bool $recursive <p>Whether array will be walked recursively or no</p> |
||
3876 | * |
||
3877 | * @return static <p>(Mutable) Return this Arrayy object, with modified elements.</p> |
||
3878 | */ |
||
3879 | 37 | public function walk($callable, bool $recursive = false) |
|
3880 | { |
||
3881 | 37 | if (true === $recursive) { |
|
3882 | 32 | \array_walk_recursive($this->array, $callable); |
|
3883 | } else { |
||
3884 | 18 | \array_walk($this->array, $callable); |
|
3885 | } |
||
3886 | |||
3887 | 37 | return $this; |
|
3888 | } |
||
3889 | } |
||
3890 |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.