Completed
Push — master ( 50a487...b105b3 )
by Lars
02:16
created

Arrayy::countValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Arrayy;
4
5
use voku\helper\UTF8;
6
7
/** @noinspection ClassReImplementsParentInterfaceInspection */
8
9
/**
10
 * Methods to manage arrays.
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
class Arrayy extends \ArrayObject implements \IteratorAggregate, \ArrayAccess, \Serializable, \Countable
16
{
17
  /**
18
   * @var array
19
   */
20
  protected $array = array();
21
22
  /**
23
   * @var string
24
   */
25
  protected $iteratorClass;
26
27
  /**
28
   * @var string
29
   */
30
  protected $pathSeparator = '.';
31
32
  /** @noinspection MagicMethodsValidityInspection */
33
  /**
34
   * Initializes
35
   *
36
   * @param array  $array
37
   * @param string $iteratorClass
38
   */
39 768
  public function __construct($array = array(), $iteratorClass = '\\Arrayy\\ArrayyIterator')
40
  {
41 768
    $array = $this->fallbackForArray($array);
42 766
    $this->array = $array;
43
44 766
    $this->setIteratorClass($iteratorClass);
45 766
  }
46
47
  /**
48
   * Get a value by key.
49
   *
50
   * @param $key
51
   *
52
   * @return mixed <p>Get a Value from the current array.</p>
53
   */
54 2
  public function &__get($key)
55
  {
56 2
    $return = $this->get($key);
57
58 2
    if (is_array($return)) {
59
      return static::create($return);
60
    }
61
62 2
    return $return;
63
  }
64
65
  /**
66
   * Call object as function.
67
   *
68
   * @param mixed $key
69
   *
70
   * @return mixed
71
   */
72 1
  public function __invoke($key = null)
73
  {
74 1
    if ($key !== null) {
75 1
      if (isset($this->array[$key])) {
76 1
        return $this->array[$key];
77
      }
78
79
      return false;
80
    }
81
82
    return (array)$this->array;
83
  }
84
85
  /**
86
   * Whether or not an element exists by key.
87
   *
88
   * @param mixed $key
89
   *
90
   * @return bool <p>True is the key/index exists, otherwise false.</p>
91
   */
92
  public function __isset($key)
93
  {
94
    return $this->offsetExists($key);
95
  }
96
97
  /**
98
   * Assigns a value to the specified element.
99
   *
100
   * @param mixed $key
101
   * @param mixed $value
102
   */
103 2
  public function __set($key, $value)
104
  {
105 2
    $this->internalSet($key, $value);
106 2
  }
107
108
  /**
109
   * magic to string
110
   *
111
   * @return string
112
   */
113 16
  public function __toString()
114
  {
115 16
    return $this->toString();
116
  }
117
118
  /**
119
   * Unset element by key.
120
   *
121
   * @param mixed $key
122
   */
123
  public function __unset($key)
124
  {
125
    $this->internalRemove($key);
126
  }
127
128
  /**
129
   * alias: for "Arrayy->append()"
130
   *
131
   * @see Arrayy::append()
132
   *
133
   * @param mixed $value
134
   *
135
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
136
   */
137 1
  public function add($value)
138
  {
139 1
    return $this->append($value);
140
  }
141
142
  /**
143
   * Append a value to the current array.
144
   *
145
   * @param mixed $value
146
   *
147
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
148
   */
149 9
  public function append($value)
150
  {
151 9
    $this->array[] = $value;
152
153 9
    return $this;
154
  }
155
156
  /**
157
   * Sort the entries by value.
158
   *
159
   * @param int $sort_flags [optional] <p>
160
   *                        You may modify the behavior of the sort using the optional
161
   *                        parameter sort_flags, for details
162
   *                        see sort.
163
   *                        </p>
164
   *
165
   * @return static <p>(Mutable) Return this Arrayy object.</p>
166
   */
167 4
  public function asort($sort_flags = null)
168
  {
169 4
    asort($this->array, $sort_flags);
170
171 4
    return $this;
172
  }
173
174
  /**
175
   * Count the values from the current array.
176
   *
177
   * alias: for "Arrayy->size()"
178
   *
179
   * @see Arrayy::size()
180
   *
181
   * @return int
182
   */
183 93
  public function count()
184
  {
185 93
    return $this->size();
186
  }
187
188
  /**
189
   * Counts all the values of an array
190
   *
191
   * @link http://php.net/manual/en/function.array-count-values.php
192
   *
193
   * @return static <p>
194
   *                (Immutable)
195 1
   *                An associative Arrayy-object of values from input as
196
   *                keys and their count as value.
197 1
   *                </p>
198
   */
199 1
  public function countValues()
200
  {
201
    return new static(\array_count_values($this->array));
202
  }
203
204
  /**
205
   * Exchange the array for another one.
206
   *
207 1
   * @param array|Arrayy $data
208
   *
209 1
   * @return array
210
   */
211
  public function exchangeArray($data)
212
  {
213
    $this->array = $this->fallbackForArray($data);
214
215
    return $this->array;
216
  }
217 20
218
  /**
219 20
   * Creates a copy of the ArrayyObject.
220
   *
221 20
   * @return array
222
   */
223
  public function getArrayCopy()
224
  {
225
    return $this->array;
226
  }
227
228
  /**
229 20
   * Returns a new ArrayyIterator, thus implementing the IteratorAggregate interface.
230
   *
231 20
   * @return ArrayyIterator <p>An iterator for the values in the array.</p>
232
   */
233
  public function getIterator()
234
  {
235
    $iterator = $this->getIteratorClass();
236
237
    return new $iterator($this->array);
238
  }
239
240
  /**
241
   * Gets the iterator classname for the ArrayObject.
242
   *
243
   * @return string
244
   */
245 4
  public function getIteratorClass()
246
  {
247 4
    return $this->iteratorClass;
248
  }
249 4
250
  /**
251
   * Sort the entries by key
252
   *
253
   * @param int $sort_flags [optional] <p>
254
   *                        You may modify the behavior of the sort using the optional
255
   *                        parameter sort_flags, for details
256
   *                        see sort.
257
   *                        </p>
258
   *
259
   * @return static <p>(Mutable) Return this Arrayy object.</p>
260
   */
261
  public function ksort($sort_flags = null)
262
  {
263
    ksort($this->array, $sort_flags);
264
265
    return $this;
266
  }
267
268
  /**
269 1
   * Sort an array using a case insensitive "natural order" algorithm
270
   *
271 1
   * @return static <p>(Mutable) Return this Arrayy object.</p>
272
   */
273 1
  public function natcasesort()
274
  {
275
    natcasesort($this->array);
276
277
    return $this;
278
  }
279
280
  /**
281
   * Sort entries using a "natural order" algorithm
282
   *
283 40
   * @return static <p>(Mutable) Return this Arrayy object.</p>
284
   */
285 40
  public function natsort()
286 4
  {
287
    natsort($this->array);
288
289
    return $this;
290 36
  }
291 1
292 1
  /**
293
   * Whether or not an offset exists.
294 36
   *
295
   * @param int|float|string $offset
296
   *
297
   * @return bool
298 36
   */
299
  public function offsetExists($offset)
300
  {
301 12
    if ($this->isEmpty()) {
302 12
      return false;
303 12
    }
304 36
305 34
    // php cast "bool"-index into "int"-index
306
    if ((bool)$offset === $offset) {
307
      $offset = (int)$offset;
308 3
    }
309
310 3
    $tmpReturn = \array_key_exists($offset, $this->array);
311
312 3
    if (
313 3
        $tmpReturn === true
314 3
        ||
315 3
        (
316
            $tmpReturn === false
317 3
            &&
318 3
            strpos((string)$offset, $this->pathSeparator) === false
319
        )
320 3
    ) {
321 3
      return $tmpReturn;
322 3
    }
323 3
324
    $offsetExists = false;
325 3
326
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
327
328
      $offsetExists = false;
329
      $explodedPath = explode($this->pathSeparator, (string)$offset);
330
      $lastOffset = \array_pop($explodedPath);
331
      $containerPath = implode($this->pathSeparator, $explodedPath);
332
333
      $this->callAtPath(
334
          $containerPath,
335 26
          function ($container) use ($lastOffset, &$offsetExists) {
336
            $offsetExists = \array_key_exists($lastOffset, $container);
337 26
          }
338
      );
339
    }
340
341
    return $offsetExists;
342
  }
343
344
  /**
345
   * Returns the value at specified offset.
346 17
   *
347
   * @param mixed $offset
348 17
   *
349 4
   * @return mixed <p>Will return null if the offset did not exists.</p>
350 4
   */
351 13
  public function offsetGet($offset)
352
  {
353 17
    return $this->offsetExists($offset) ? $this->get($offset) : null;
354
  }
355
356
  /**
357
   * Assigns a value to the specified offset.
358
   *
359
   * @param mixed $offset
360 7
   * @param mixed $value
361
   */
362 7
  public function offsetSet($offset, $value)
363 1
  {
364
    if ($offset === null) {
365
      $this->array[] = $value;
366 6
    } else {
367 4
      $this->internalSet($offset, $value);
368
    }
369 4
  }
370
371
  /**
372 3
   * Unset an offset.
373
   *
374 2
   * @param mixed $offset
375 2
   */
376
  public function offsetUnset($offset)
377 2
  {
378 2
    if ($this->isEmpty()) {
379
      return;
380 2
    }
381 2
382 2
    if (\array_key_exists($offset, $this->array)) {
383
      unset($this->array[$offset]);
384 2
385 3
      return;
386
    }
387
388
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
389
390
      $path = explode($this->pathSeparator, (string)$offset);
391
      $pathToUnset = \array_pop($path);
392 1
393
      $this->callAtPath(
394 1
          implode($this->pathSeparator, $path),
395
          function (&$offset) use ($pathToUnset) {
396
            unset($offset[$pathToUnset]);
397
          }
398
      );
399
400
    }
401
  }
402
403
  /**
404
   * Serialize the current "Arrayy"-object.
405
   *
406 766
   * @return string
407
   */
408 766
  public function serialize()
409 766
  {
410
    return parent::serialize();
411 766
  }
412
413
  /**
414
   * Sets the iterator classname for the current "Arrayy"-object.
415
   *
416
   * @param  string $class
417
   *
418
   * @return void
419
   *
420
   * @throws \InvalidArgumentException
421
   */
422
  public function setIteratorClass($class)
423
  {
424
    if (class_exists($class)) {
425
      $this->iteratorClass = $class;
426
427
      return;
428
    }
429
430
    if (strpos($class, '\\') === 0) {
431
      $class = '\\' . $class;
432
      if (class_exists($class)) {
433
        $this->iteratorClass = $class;
434
435
        return;
436
      }
437
    }
438
439
    throw new \InvalidArgumentException('The iterator class does not exist: ' . $class);
440
  }
441
442
  /**
443
   * Sort the entries with a user-defined comparison function and maintain key association.
444
   *
445
   * @param callable $function
446
   *
447
   * @return static <p>(Mutable) Return this Arrayy object.</p>
448
   *
449
   * @throws \InvalidArgumentException
450
   */
451 View Code Duplication
  public function uasort($function)
0 ignored issues
show
Duplication introduced by
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...
452
  {
453
    if (!is_callable($function)) {
454
      throw new \InvalidArgumentException(
455
          'Passed function must be callable'
456
      );
457 5
    }
458
459 5
    uasort($this->array, $function);
460
461
    return $this;
462
  }
463
464
  /**
465
   * Sort the entries by keys using a user-defined comparison function.
466
   *
467
   * @param callable $function
468
   *
469 1
   * @return static <p>(Mutable) Return this Arrayy object.</p>
470
   *
471 1
   * @throws \InvalidArgumentException
472
   */
473 1
  public function uksort($function)
474
  {
475
    return $this->customSortKeys($function);
476
  }
477
478
  /**
479
   * Unserialize an string and return this object.
480
   *
481 4
   * @param string $string
482
   *
483 4
   * @return static <p>(Mutable)</p>
484
   */
485 4
  public function unserialize($string)
486
  {
487
    parent::unserialize($string);
488
489
    return $this;
490
  }
491
492
  /**
493
   * Sort an array in reverse order and maintain index association.
494
   *
495 2
   * @return static <p>(Mutable) Return this Arrayy object.</p>
496
   */
497 2
  public function arsort()
498
  {
499 2
    arsort($this->array);
500 2
501 2
    return $this;
502
  }
503 2
504
  /**
505
   * Iterate over the current array and execute a callback for each loop.
506
   *
507
   * @param \Closure $closure
508
   *
509
   * @return static <p>(Immutable)</p>
510
   */
511 View Code Duplication
  public function at(\Closure $closure)
0 ignored issues
show
Duplication introduced by
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...
512
  {
513 10
    $array = $this->array;
514
515 10
    foreach ($array as $key => $value) {
516
      $closure($value, $key);
517 10
    }
518 2
519
    return static::create($array);
520
  }
521 8
522 3
  /**
523 3
   * Returns the average value of the current array.
524
   *
525 8
   * @param int $decimals <p>The number of decimal-numbers to return.</p>
526
   *
527
   * @return int|double <p>The average value.</p>
528
   */
529
  public function average($decimals = 0)
530
  {
531
    $count = $this->count();
532
533 4
    if (!$count) {
534
      return 0;
535 4
    }
536 4
537 4
    if (!is_int($decimals)) {
538
      $decimals = 0;
539 4
    }
540 4
541
    return round(\array_sum($this->array) / $count, $decimals);
542 4
  }
543
544
  /**
545
   * @param mixed      $path
546 4
   * @param callable   $callable
547 1
   * @param null|array $currentOffset
548 1
   */
549 1
  protected function callAtPath($path, $callable, &$currentOffset = null)
550 1
  {
551 1
    if ($currentOffset === null) {
552 1
      $currentOffset = &$this->array;
553 4
    }
554
555 4
    $explodedPath = explode($this->pathSeparator, $path);
556
    $nextPath = \array_shift($explodedPath);
557
558
    if (!isset($currentOffset[$nextPath])) {
559
      return;
560
    }
561
562
    if (!empty($explodedPath)) {
563
      $this->callAtPath(
564
          implode($this->pathSeparator, $explodedPath),
565 1
          $callable,
566
          $currentOffset[$nextPath]
567 1
      );
568
    } else {
569
      $callable($currentOffset[$nextPath]);
570
    }
571
  }
572
573
  /**
574
   * Changes all keys in an array.
575
   *
576
   * @param int $case [optional] <p> Either <strong>CASE_UPPER</strong><br />
577
   *                  or <strong>CASE_LOWER</strong> (default)</p>
578
   *
579 1
   * @return static <p>(Immutable)</p>
580
   */
581 1
  public function changeKeyCase($case = CASE_LOWER)
582
  {
583 1
    return static::create(UTF8::array_change_key_case($this->array, $case));
0 ignored issues
show
Security Bug introduced by
It seems like \voku\helper\UTF8::array...se($this->array, $case) targeting voku\helper\UTF8::array_change_key_case() can also be of type false; however, Arrayy\Arrayy::create() does only seem to accept array, did you maybe forget to handle an error condition?
Loading history...
584
  }
585
586
  /**
587
   * Change the path separator of the array wrapper.
588
   *
589
   * By default, the separator is: "."
590
   *
591
   * @param string $separator <p>Separator to set.</p>
592
   *
593
   * @return static <p>Mutable</p>
594 4
   */
595
  public function changeSeparator($separator)
596 4
  {
597
    $this->pathSeparator = $separator;
598 4
599
    return $this;
600
  }
601
602
  /**
603
   * Create a chunked version of the current array.
604
   *
605
   * @param int  $size         <p>Size of each chunk.</p>
606 8
   * @param bool $preserveKeys <p>Whether array keys are preserved or no.</p>
607
   *
608 8
   * @return static <p>(Immutable) A new array of chunks from the original array.</p>
609
   */
610 7
  public function chunk($size, $preserveKeys = false)
611
  {
612 8
    $result = \array_chunk($this->array, $size, $preserveKeys);
613
614
    return static::create($result);
615
  }
616
617
  /**
618
   * Clean all falsy values from the current array.
619
   *
620 4
   * @return static <p>(Immutable)</p>
621
   */
622 4
  public function clean()
623
  {
624 4
    return $this->filter(
625
        function ($value) {
626
          return (bool)$value;
627
        }
628
    );
629
  }
630
631
  /**
632
   * WARNING!!! -> Clear the current array.
633
   *
634 13
   * @return static <p>(Mutable) Return this Arrayy object, with an empty array.</p>
635
   */
636 13
  public function clear()
637
  {
638
    $this->array = array();
639
640
    return $this;
641
  }
642
643
  /**
644
   * Check if an item is in the current array.
645
   *
646 13
   * @param string|int|float $value
647
   *
648 13
   * @return bool
649 13
   */
650 13
  public function contains($value)
651
  {
652 13
    return in_array($value, $this->array, true);
653 13
  }
654 13
655 13
  /**
656 13
   * Check if an (case-insensitive) string is in the current array.
657
   *
658 13
   * @param string $value
659
   *
660
   * @return bool
661
   */
662
  public function containsCaseInsensitive($value)
663
  {
664
    return in_array(
665
        UTF8::strtolower($value),
666
        \array_map(
667
            array(
668 4
                new UTF8(),
669
                'strtolower',
670 4
            ),
671
            $this->array
672
        ),
673
        true
674
    );
675
  }
676
677
  /**
678
   * Check if the given key/index exists in the array.
679
   *
680 1
   * @param string|int|float $key <p>key/index to search for</p>
681
   *
682 1
   * @return bool <p>Returns true if the given key/index exists in the array, false otherwise.</p>
683
   */
684
  public function containsKey($key)
685
  {
686
    return $this->offsetExists($key);
687
  }
688
689
  /**
690
   * Check if all given needles are present in the array as key/index.
691
   *
692
   * @param array $needles
693
   *
694 9
   * @return bool <p>Returns true if the given keys/indexes exists in the array, false otherwise.</p>
695
   */
696 9
  public function containsKeys(array $needles)
697
  {
698
    return count(\array_intersect($needles, $this->keys()->getArray())) === count($needles);
699
  }
700
701
  /**
702
   * alias: for "Arrayy->contains()"
703
   *
704
   * @see Arrayy::contains()
705
   *
706 1
   * @param string|int|float $value
707
   *
708 1
   * @return bool
709
   */
710
  public function containsValue($value)
711
  {
712
    return $this->contains($value);
713
  }
714
715
  /**
716
   * Check if all given needles are present in the array.
717
   *
718 480
   * @param array $needles
719
   *
720 480
   * @return bool <p>Returns true if the given values exists in the array, false otherwise.</p>
721
   */
722
  public function containsValues(array $needles)
723
  {
724
    return count(\array_intersect($needles, $this->array)) === count($needles);
725
  }
726
727
  /**
728
   * Creates an Arrayy object.
729
   *
730 1
   * @param array $array
731
   *
732 1
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
733
   */
734 1
  public static function create($array = array())
735
  {
736 1
    return new static($array);
737
  }
738
739
  /**
740
   * WARNING: Creates an Arrayy object by reference.
741
   *
742
   * @param array $array
743
   *
744
   * @return static <p>(Mutable) Return this Arrayy object.</p>
745
   */
746 5
  public function createByReference(&$array = array())
747
  {
748 5
    $array = $this->fallbackForArray($array);
749
750 5
    $this->array = &$array;
751
752
    return $this;
753
  }
754
755
  /**
756
   * Create an new Arrayy object via JSON.
757
   *
758
   * @param string $json
759
   *
760 4
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
761
   */
762 4
  public static function createFromJson($json)
763 4
  {
764
    $array = UTF8::json_decode($json, true);
765 3
766 4
    return static::create($array);
767
  }
768 4
769
  /**
770
   * Create an new instance filled with values from an object that have implemented ArrayAccess.
771
   *
772
   * @param \ArrayAccess $object <p>Object that implements ArrayAccess</p>
773
   *
774
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
775
   */
776
  public static function createFromObject(\ArrayAccess $object)
777
  {
778
    $array = new static();
779
    foreach ($object as $key => $value) {
780
      /** @noinspection OffsetOperationsInspection */
781 8
      $array[$key] = $value;
782
    }
783 8
784 1
    return $array;
785
  }
786 1
787 1
  /**
788 1
   * Create an new Arrayy object via string.
789
   *
790 1
   * @param string      $str       <p>The input string.</p>
791 7
   * @param string|null $delimiter <p>The boundary string.</p>
792
   * @param string|null $regEx     <p>Use the $delimiter or the $regEx, so if $pattern is null, $delimiter will be
793
   *                               used.</p>
794
   *
795 8
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
796
   */
797
  public static function createFromString($str, $delimiter, $regEx = null)
798
  {
799 8
    if ($regEx) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $regEx of type string|null 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 ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
800 8
      preg_match_all($regEx, $str, $array);
801 8
802 8
      if (!empty($array)) {
803 8
        $array = $array[0];
804
      }
805 8
806
    } else {
807
      $array = explode($delimiter, $str);
808
    }
809
810
    // trim all string in the array
811
    \array_walk(
812
        $array,
813
        function (&$val) {
814
          /** @noinspection ReferenceMismatchInspection */
815
          if (is_string($val)) {
816
            $val = trim($val);
817 1
          }
818
        }
819 1
    );
820
821
    return static::create($array);
822
  }
823
824
  /**
825
   * Create an new instance containing a range of elements.
826
   *
827
   * @param mixed $low  <p>First value of the sequence.</p>
828
   * @param mixed $high <p>The sequence is ended upon reaching the end value.</p>
829
   * @param int   $step <p>Used as the increment between elements in the sequence.</p>
830
   *
831
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
832
   */
833 5
  public static function createWithRange($low, $high, $step = 1)
834
  {
835 5
    return static::create(range($low, $high, $step));
836
  }
837
838
  /**
839
   * Custom sort by index via "uksort".
840
   *
841 5
   * @link http://php.net/manual/en/function.uksort.php
842
   *
843 5
   * @param callable $function
844
   *
845
   * @return static <p>(Mutable) Return this Arrayy object.</p>
846
   *
847
   * @throws \InvalidArgumentException
848
   */
849 View Code Duplication
  public function customSortKeys($function)
0 ignored issues
show
Duplication introduced by
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...
850
  {
851
    if (!is_callable($function)) {
852
      throw new \InvalidArgumentException(
853
          'Passed function must be callable'
854
      );
855
    }
856
857 5
    uksort($this->array, $function);
858
859 5
    return $this;
860
  }
861
862
  /**
863
   * Custom sort by value via "usort".
864
   *
865 5
   * @link http://php.net/manual/en/function.usort.php
866
   *
867 5
   * @param callable $function
868
   *
869
   * @return static <p>(Mutable) Return this Arrayy object.</p>
870
   *
871
   * @throws \InvalidArgumentException
872
   */
873 View Code Duplication
  public function customSortValues($function)
0 ignored issues
show
Duplication introduced by
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...
874
  {
875
    if (!is_callable($function)) {
876
      throw new \InvalidArgumentException(
877 12
          'Passed function must be callable'
878
      );
879 12
    }
880
881 12
    usort($this->array, $function);
882
883
    return $this;
884
  }
885
886
  /**
887
   * Return values that are only in the current array.
888
   *
889
   * @param array $array
890
   *
891
   * @return static <p>(Immutable)</p>
892 1
   */
893
  public function diff(array $array = array())
894 1
  {
895
    $result = \array_diff($this->array, $array);
896
897
    return static::create($result);
898 1
  }
899 1
900 1
  /**
901 1
   * Return values that are only in the current multi-dimensional array.
902 1
   *
903 1
   * @param array      $array
904
   * @param null|array $helperVariableForRecursion <p>(only for internal usage)</p>
905
   *
906 1
   * @return static <p>(Immutable)</p>
907 1
   */
908 1
  public function diffRecursive(array $array = array(), $helperVariableForRecursion = null)
909 1
  {
910 1
    $result = array();
911 1
912 1
    if (
913 1
        $helperVariableForRecursion !== null
914 1
        &&
915 1
        is_array($helperVariableForRecursion)
916 1
    ) {
917
      $arrayForTheLoop = $helperVariableForRecursion;
918 1
    } else {
919 1
      $arrayForTheLoop = $this->array;
920
    }
921 1
922
    foreach ($arrayForTheLoop as $key => $value) {
923 1
      if (\array_key_exists($key, $array)) {
924
        if (is_array($value)) {
925
          $recursiveDiff = $this->diffRecursive($array[$key], $value);
926
          if (!empty($recursiveDiff)) {
927
            $result[$key] = $recursiveDiff;
928
          }
929
        } else {
930
          if ($value != $array[$key]) {
931
            $result[$key] = $value;
932
          }
933 8
        }
934
      } else {
935 8
        $result[$key] = $value;
936
      }
937 8
    }
938
939
    return static::create($result);
940
  }
941
942
  /**
943
   * Return values that are only in the new $array.
944
   *
945 1
   * @param array $array
946
   *
947 1
   * @return static <p>(Immutable)</p>
948
   */
949 1
  public function diffReverse(array $array = array())
950 1
  {
951
    $result = \array_diff($array, $this->array);
952 1
953
    return static::create($result);
954
  }
955
956
  /**
957
   * Divide an array into two arrays. One with keys and the other with values.
958
   *
959
   * @return static <p>(Immutable)</p>
960
   */
961
  public function divide()
962 4
  {
963
    return static::create(
964 4
        array(
965
            $this->keys(),
966 4
            $this->values(),
967 4
        )
968 4
    );
969
  }
970 4
971
  /**
972
   * Iterate over the current array and modify the array's value.
973
   *
974
   * @param \Closure $closure
975
   *
976
   * @return static <p>(Immutable)</p>
977
   */
978 View Code Duplication
  public function each(\Closure $closure)
0 ignored issues
show
Duplication introduced by
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...
979
  {
980 4
    $array = $this->array;
981
982 4
    foreach ($array as $key => $value) {
983 4
      $array[$key] = $closure($value, $key);
984 3
    }
985 1
986 1
    return static::create($array);
987
  }
988 4
989
  /**
990 4
   * Check if a value is in the current array using a closure.
991
   *
992
   * @param \Closure $closure
993
   *
994
   * @return bool <p>Returns true if the given value is found, false otherwise.</p>
995
   */
996
  public function exists(\Closure $closure)
997
  {
998
    $isExists = false;
999
    foreach ($this->array as $key => $value) {
1000
      if ($closure($value, $key)) {
1001
        $isExists = true;
1002
        break;
1003
      }
1004
    }
1005
1006
    return $isExists;
1007
  }
1008
1009
  /**
1010 768
   * create a fallback for array
1011
   *
1012 768
   * 1. use the current array, if it's a array
1013 765
   * 2. call "getArray()" on object, if there is a "Arrayy"-object
1014
   * 3. fallback to empty array, if there is nothing
1015
   * 4. call "createFromObject()" on object, if there is a "\ArrayAccess"-object
1016 11
   * 5. call "__toArray()" on object, if the method exists
1017 1
   * 6. cast a string or object with "__toString()" into an array
1018
   * 7. throw a "InvalidArgumentException"-Exception
1019
   *
1020 10
   * @param $array
1021 6
   *
1022
   * @return array
1023
   *
1024 9
   * @throws \InvalidArgumentException
1025
   */
1026 9
  protected function fallbackForArray(&$array)
1027
  {
1028
    if (is_array($array)) {
1029
      return $array;
1030
    }
1031 9
1032
    if ($array instanceof self) {
1033
      return $array->getArray();
1034
    }
1035 9
1036
    if (!$array) {
1037
      return array();
1038
    }
1039
1040
    $isObject = is_object($array);
1041 9
1042
    if ($isObject && $array instanceof \ArrayAccess) {
1043 2
      /** @noinspection ReferenceMismatchInspection */
1044 9
      return static::createFromObject($array)->getArray();
1045 7
    }
1046
1047
    if ($isObject && $array instanceof \ArrayObject) {
1048 2
      return $array->getArrayCopy();
1049
    }
1050 2
1051
    if ($isObject && method_exists($array, '__toArray')) {
1052
      return (array)$array->__toArray();
1053
    }
1054
1055
    /** @noinspection ReferenceMismatchInspection */
1056
    if (
1057
        is_string($array)
1058
        ||
1059
        ($isObject && method_exists($array, '__toString'))
1060 9
    ) {
1061
      return array((string)$array);
1062 9
    }
1063 1
1064
    throw new \InvalidArgumentException(
1065
        'Passed value should be a array'
1066 9
    );
1067
  }
1068 9
1069
  /**
1070
   * Find all items in an array that pass the truth test.
1071
   *
1072
   * @param \Closure|null $closure [optional] <p>
1073
   *                               The callback function to use
1074
   *                               </p>
1075
   *                               <p>
1076
   *                               If no callback is supplied, all entries of
1077
   *                               input equal to false (see
1078
   *                               converting to
1079
   *                               boolean) will be removed.
1080
   *                               </p>
1081
   *
1082
   *  * @param int $flag [optional] <p>
1083
   *                               Flag determining what arguments are sent to <i>callback</i>:
1084
   *                               </p><ul>
1085
   *                               <li>
1086
   *                               <b>ARRAY_FILTER_USE_KEY</b> - pass key as the only argument
1087
   *                               to <i>callback</i> instead of the value</span>
1088
   *                               </li>
1089
   *                               <li>
1090
   *                               <b>ARRAY_FILTER_USE_BOTH</b> - pass both value and key as
1091
   *                               arguments to <i>callback</i> instead of the value</span>
1092
   *                               </li>
1093 1
   *                               </ul>
1094
   *
1095 1
   * @return static <p>(Immutable)</p>
1096 1
   */
1097 1
  public function filter($closure = null, $flag = 0)
1098
  {
1099
    if (!$closure) {
1100
      return $this->clean();
1101 1
    }
1102 1
1103
    $array = \array_filter($this->array, $closure, $flag);
1104
1105 1
    return static::create($array);
1106
  }
1107
1108 1
  /**
1109
   * Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property
1110
   * within that.
1111 1
   *
1112
   * @param string $property
1113 1
   * @param string $value
1114 1
   * @param string $comparisonOp
1115
   *                            <p>
1116
   *                            'eq' (equals),<br />
1117 1
   *                            'gt' (greater),<br />
1118
   *                            'gte' || 'ge' (greater or equals),<br />
1119
   *                            'lt' (less),<br />
1120 1
   *                            'lte' || 'le' (less or equals),<br />
1121
   *                            'ne' (not equals),<br />
1122
   *                            'contains',<br />
1123 1
   *                            'notContains',<br />
1124
   *                            'newer' (via strtotime),<br />
1125 1
   *                            'older' (via strtotime),<br />
1126 1
   *                            </p>
1127
   *
1128
   * @return static <p>(Immutable)</p>
1129 1
   */
1130
  public function filterBy($property, $value, $comparisonOp = null)
1131
  {
1132 1
    if (!$comparisonOp) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $comparisonOp of type string|null 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 ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
1133
      $comparisonOp = is_array($value) ? 'contains' : 'eq';
1134
    }
1135 1
1136 1
    $ops = array(
1137
        'eq'          => function ($item, $prop, $value) {
1138 1
          return $item[$prop] === $value;
1139 1
        },
1140 1
        'gt'          => function ($item, $prop, $value) {
1141
          return $item[$prop] > $value;
1142 1
        },
1143 1
        'ge'          => function ($item, $prop, $value) {
1144 1
          return $item[$prop] >= $value;
1145 1
        },
1146
        'gte'         => function ($item, $prop, $value) {
1147 1
          return $item[$prop] >= $value;
1148 1
        },
1149 1
        'lt'          => function ($item, $prop, $value) {
1150
          return $item[$prop] < $value;
1151 1
        },
1152
        'le'          => function ($item, $prop, $value) {
1153 1
          return $item[$prop] <= $value;
1154 1
        },
1155
        'lte'         => function ($item, $prop, $value) {
1156 1
          return $item[$prop] <= $value;
1157
        },
1158
        'ne'          => function ($item, $prop, $value) {
1159
          return $item[$prop] !== $value;
1160
        },
1161
        'contains'    => function ($item, $prop, $value) {
1162
          return in_array($item[$prop], (array)$value, true);
1163
        },
1164
        'notContains' => function ($item, $prop, $value) {
1165
          return !in_array($item[$prop], (array)$value, true);
1166
        },
1167 8
        'newer'       => function ($item, $prop, $value) {
1168
          return strtotime($item[$prop]) > strtotime($value);
1169 8
        },
1170 6
        'older'       => function ($item, $prop, $value) {
1171 5
          return strtotime($item[$prop]) < strtotime($value);
1172
        },
1173 5
    );
1174
1175 3
    $result = \array_values(
1176
        \array_filter(
1177
            (array)$this->array,
1178
            function ($item) use (
1179
                $property,
1180
                $value,
1181
                $ops,
1182
                $comparisonOp
1183
            ) {
1184
              $item = (array)$item;
1185
              $itemArrayy = new Arrayy($item);
1186
              $item[$property] = $itemArrayy->get($property, array());
1187
1188
              return $ops[$comparisonOp]($item, $property, $value);
1189
            }
1190
        )
1191
    );
1192
1193
    return static::create($result);
1194
  }
1195
1196
  /**
1197 13
   * Find the first item in an array that passes the truth test,
1198
   *  otherwise return false
1199 13
   *
1200 13
   * @param \Closure $closure
1201
   *
1202 13
   * @return mixed|false <p>Return false if we did not find the value.</p>
1203 3
   */
1204
  public function find(\Closure $closure)
1205
  {
1206 10
    foreach ($this->array as $key => $value) {
1207
      if ($closure($value, $key)) {
1208
        return $value;
1209
      }
1210
    }
1211
1212
    return false;
1213
  }
1214
1215
  /**
1216 28
   * find by ...
1217
   *
1218 28
   * @param string $property
1219 7
   * @param string $value
1220 7
   * @param string $comparisonOp
1221 7
   *
1222 21
   * @return static <p>(Immutable)</p>
1223 21
   */
1224 21
  public function findBy($property, $value, $comparisonOp = 'eq')
1225
  {
1226
    return $this->filterBy($property, $value, $comparisonOp);
1227 28
  }
1228
1229
  /**
1230
   * Get the first value from the current array.
1231
   *
1232
   * @return mixed <p>Return null if there wasn't a element.</p>
1233
   */
1234
  public function first()
1235
  {
1236
    $tmpArray = $this->array;
1237 26
    $result = \array_shift($tmpArray);
1238
1239 26
    if ($result === null) {
1240 11
      return null;
1241 11
    }
1242 15
1243 15
    return $result;
1244
  }
1245
1246 26
  /**
1247
   * Get the first value(s) from the current array.
1248
   *
1249
   * @param int|null $number <p>How many values you will take?</p>
1250
   *
1251
   * @return static <p>(Immutable)</p>
1252
   */
1253
  public function firstsImmutable($number = null)
1254 1
  {
1255
    if ($number === null) {
1256 1
      $arrayTmp = $this->array;
1257
      $array = (array)\array_shift($arrayTmp);
1258 1
    } else {
1259
      $number = (int)$number;
1260
      $arrayTmp = $this->array;
1261
      $array = \array_splice($arrayTmp, 0, $number, true);
1262
    }
1263
1264
    return static::create($array);
1265
  }
1266
1267
  /**
1268
   * Get the first value(s) from the current array.
1269
   *
1270
   * @param int|null $number <p>How many values you will take?</p>
1271 61
   *
1272
   * @return static <p>(Mutable)</p>
1273
   */
1274
  public function firstsMutable($number = null)
1275 61
  {
1276 3
    if ($number === null) {
1277 61
      $this->array = (array)\array_shift($this->array);
1278 3
    } else {
1279 3
      $number = (int)$number;
1280 59
      $this->array = \array_splice($this->array, 0, $number, true);
1281
    }
1282
1283 61
    return $this;
1284 1
  }
1285
1286
  /**
1287
   * Exchanges all keys with their associated values in an array.
1288 61
   *
1289 2
   * @return static <p>(Immutable)</p>
1290 2
   */
1291
  public function flip()
1292 61
  {
1293 51
    $result = \array_flip($this->array);
1294 6
1295
    return static::create($result);
1296
  }
1297 47
1298
  /**
1299
   * Get a value from an array (optional using dot-notation).
1300
   *
1301 20
   * @param string $key      <p>The key to look for.</p>
1302 20
   * @param mixed  $fallback <p>Value to fallback to.</p>
1303 19
   * @param array  $array    <p>The array to get from, if it's set to "null" we use the current array from the
1304
   *                         class.</p>
1305
   *
1306 5
   * @return mixed
1307 5
   */
1308
  public function get($key, $fallback = null, $array = null)
1309 5
  {
1310
    if (
1311
        $array !== null
1312
        &&
1313 5
        is_array($array)
1314
    ) {
1315
      $usedArray = $array;
1316
    } else {
1317
      $usedArray = $this->array;
1318
    }
1319
1320
    if ($key === null) {
1321 490
      return static::create($usedArray);
1322
    }
1323 490
1324
    // php cast "bool"-index into "int"-index
1325 490
    if ((bool)$key === $key) {
1326
      $key = (int)$key;
1327
    }
1328
1329
    if (\array_key_exists($key, $usedArray) === true) {
1330
      if (is_array($usedArray[$key])) {
1331
        return static::create($usedArray[$key]);
1332
      }
1333
1334
      return $usedArray[$key];
1335
    }
1336
1337
    // Crawl through array, get key according to object or not
1338
    foreach (explode($this->pathSeparator, (string)$key) as $segment) {
1339
      if (!isset($usedArray[$segment])) {
1340 1
        return $fallback instanceof \Closure ? $fallback() : $fallback;
1341
      }
1342 1
1343
      $usedArray = $usedArray[$segment];
1344 1
    }
1345
1346
    if (is_array($usedArray)) {
1347
      return static::create($usedArray);
1348
    }
1349
1350
    return $usedArray;
1351
  }
1352
1353
  /**
1354 38
   * Get the current array from the "Arrayy"-object.
1355
   *
1356 38
   * @return array
1357 10
   */
1358
  public function getArray()
1359 10
  {
1360 2
    \array_map(array('self', 'internalGetArray'), $this->array);
1361 2
1362 8
    return $this->array;
1363
  }
1364 10
1365
  /**
1366
   * Returns the values from a single column of the input array, identified by
1367
   * the $columnKey, can be used to extract data-columns from multi-arrays.
1368 38
   *
1369
   * Info: Optionally, you may provide an $indexKey to index the values in the returned
1370 38
   * array by the values from the $indexKey column in the input array.
1371
   *
1372
   * @param mixed $columnKey
1373
   * @param mixed $indexKey
1374 38
   *
1375
   * @return static <p>(Immutable)</p>
1376
   */
1377
  public function getColumn($columnKey = null, $indexKey = null)
1378
  {
1379
    $result = \array_column($this->array, $columnKey, $indexKey);
1380
1381
    return static::create($result);
0 ignored issues
show
Bug introduced by
It seems like $result defined by \array_column($this->arr... $columnKey, $indexKey) on line 1379 can also be of type false or null; however, Arrayy\Arrayy::create() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
1382
  }
1383
1384 1
  /**
1385
   * Get correct PHP constant for direction.
1386 1
   *
1387
   * @param int|string $direction
1388
   *
1389
   * @return int
1390
   */
1391
  protected function getDirection($direction)
1392
  {
1393
    if (is_string($direction)) {
1394
      $direction = strtolower($direction);
1395
1396 3
      if ($direction === 'desc') {
1397
        $direction = SORT_DESC;
1398 3
      } else {
1399
        $direction = SORT_ASC;
1400
      }
1401
    }
1402
1403
    if (
1404
        $direction !== SORT_DESC
1405
        &&
1406
        $direction !== SORT_ASC
1407
    ) {
1408 3
      $direction = SORT_ASC;
1409
    }
1410 3
1411
    return $direction;
1412
  }
1413
1414
  /**
1415
   * alias: for "Arrayy->keys()"
1416
   *
1417
   * @see Arrayy::keys()
1418
   *
1419
   * @return static <p>(Immutable)</p>
1420
   */
1421
  public function getKeys()
1422 9
  {
1423
    return $this->keys();
1424 9
  }
1425
1426
  /**
1427
   * alias: for "Arrayy->randomImmutable()"
1428
   *
1429
   * @see Arrayy::randomImmutable()
1430
   *
1431
   * @return static <p>(Immutable)</p>
1432
   */
1433
  public function getRandom()
1434 3
  {
1435
    return $this->randomImmutable();
1436 3
  }
1437
1438
  /**
1439
   * alias: for "Arrayy->randomKey()"
1440
   *
1441
   * @see Arrayy::randomKey()
1442
   *
1443
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
1444
   */
1445
  public function getRandomKey()
1446
  {
1447
    return $this->randomKey();
1448 6
  }
1449
1450 6
  /**
1451
   * alias: for "Arrayy->randomKeys()"
1452
   *
1453
   * @see Arrayy::randomKeys()
1454
   *
1455
   * @param int $number
1456
   *
1457
   * @return static <p>(Immutable)</p>
1458
   */
1459
  public function getRandomKeys($number)
1460
  {
1461 3
    return $this->randomKeys($number);
1462
  }
1463 3
1464 3
  /**
1465
   * alias: for "Arrayy->randomValue()"
1466
   *
1467 3
   * @see Arrayy::randomValue()
1468
   *
1469 3
   * @return mixed <p>get a random value or null if there wasn't a value.</p>
1470 3
   */
1471
  public function getRandomValue()
1472 3
  {
1473
    return $this->randomValue();
1474
  }
1475
1476 3
  /**
1477 3
   * alias: for "Arrayy->randomValues()"
1478 3
   *
1479
   * @see Arrayy::randomValues()
1480
   *
1481 3
   * @param int $number
1482 2
   *
1483 1
   * @return static <p>(Immutable)</p>
1484 1
   */
1485 1
  public function getRandomValues($number)
1486 1
  {
1487 1
    return $this->randomValues($number);
1488
  }
1489 2
1490
  /**
1491 3
   * Group values from a array according to the results of a closure.
1492
   *
1493 3
   * @param string $grouper <p>A callable function name.</p>
1494
   * @param bool   $saveKeys
1495
   *
1496
   * @return static <p>(Immutable)</p>
1497
   */
1498
  public function group($grouper, $saveKeys = false)
1499
  {
1500
    $array = (array)$this->array;
1501
    $result = array();
1502
1503 22
    // Iterate over values, group by property/results from closure
1504
    foreach ($array as $key => $value) {
1505
1506 22
      $groupKey = is_callable($grouper) ? $grouper($value, $key) : $this->get($grouper, null, $value);
1507
      $newValue = $this->get($groupKey, null, $result);
1508 22
1509
      if ($groupKey instanceof self) {
1510
        $groupKey = $groupKey->getArray();
1511
      }
1512
1513
      if ($newValue instanceof self) {
1514
        $newValue = $newValue->getArray();
1515
      }
1516
1517
      // Add to results
1518 27
      if ($groupKey !== null) {
1519
        if ($saveKeys) {
1520 27
          $result[$groupKey] = $newValue;
1521
          $result[$groupKey][$key] = $value;
1522
        } else {
1523
          $result[$groupKey] = $newValue;
1524
          $result[$groupKey][] = $value;
1525
        }
1526
      }
1527
1528
    }
1529
1530
    return static::create($result);
1531
  }
1532
1533
  /**
1534 3
   * Check if an array has a given key.
1535
   *
1536 3
   * @param mixed $key
1537
   *
1538 3
   * @return bool
1539 3
   */
1540 2
  public function has($key)
1541 2
  {
1542 3
    // Generate unique string to use as marker.
1543
    $unFound = (string)uniqid('arrayy', true);
1544 3
1545
    return $this->get($key, $unFound) !== $unFound;
1546
  }
1547
1548
  /**
1549
   * Implodes an array.
1550
   *
1551
   * @param string $glue
1552
   *
1553
   * @return string
1554
   */
1555
  public function implode($glue = '')
1556 4
  {
1557
    return implode($glue, $this->array);
1558 4
  }
1559
1560
  /**
1561
   * Given a list and an iterate-function that returns
1562
   * a key for each element in the list (or a property name),
1563
   * returns an object with an index of each item.
1564
   *
1565
   * Just like groupBy, but for when you know your keys are unique.
1566
   *
1567
   * @param mixed $key
1568 12
   *
1569
   * @return static <p>(Immutable)</p>
1570 12
   */
1571
  public function indexBy($key)
1572 12
  {
1573
    $results = array();
1574
1575
    foreach ($this->array as $a) {
1576
      if (\array_key_exists($key, $a) === true) {
1577
        $results[$a[$key]] = $a;
1578 405
      }
1579
    }
1580 405
1581
    return static::create($results);
1582 405
  }
1583
1584
  /**
1585 405
   * alias: for "Arrayy->searchIndex()"
1586
   *
1587
   * @see Arrayy::searchIndex()
1588
   *
1589
   * @param mixed $value <p>The value to search for.</p>
1590
   *
1591
   * @return mixed
1592
   */
1593
  public function indexOf($value)
1594 18
  {
1595
    return $this->searchIndex($value);
1596 18
  }
1597
1598
  /**
1599 18
   * Get everything but the last..$to items.
1600
   *
1601
   * @param int $to
1602
   *
1603
   * @return static <p>(Immutable)</p>
1604
   */
1605
  public function initial($to = 1)
1606
  {
1607
    $slice = count($this->array) - $to;
1608
1609 18
    return $this->firstsImmutable($slice);
1610
  }
1611 18
1612
  /**
1613 18
   * @param mixed $value
1614
   */
1615
  protected function internalGetArray(&$value)
1616
  {
1617
    if ($value instanceof self) {
1618
      $value &= $value->getArray();
1619
    } elseif ($value instanceof \JsonSerializable) {
0 ignored issues
show
Bug introduced by
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 dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
1620
      $value &= $value->jsonSerialize();
1621
    }
1622
  }
1623
1624 30
  /**
1625
   * Internal mechanics of remove method.
1626 30
   *
1627
   * @param string $key
1628
   *
1629
   * @return boolean
1630
   */
1631 30
  protected function internalRemove($key)
1632 30
  {
1633
    $path = explode($this->pathSeparator, (string)$key);
1634
1635 30
    // Crawl though the keys
1636 3
    while (count($path) > 1) {
1637
      $key = \array_shift($path);
1638
1639
      if (!$this->has($key)) {
1640
        return false;
1641 3
      }
1642
1643
      $this->array = &$this->array[$key];
1644
    }
1645 3
1646 3
    $key = \array_shift($path);
1647
1648 30
    unset($this->array[$key]);
1649
1650 30
    return true;
1651
  }
1652
1653
  /**
1654
   * Internal mechanic of set method.
1655
   *
1656
   * @param string $key
1657
   * @param mixed  $value
1658
   *
1659
   * @return bool
1660 2
   */
1661
  protected function internalSet($key, $value)
1662 2
  {
1663
    if ($key === null) {
1664
      return false;
1665
    }
1666
1667
    // init
1668
    $array =& $this->array;
1669
    $path = explode($this->pathSeparator, (string)$key);
1670
1671
    // Crawl through the keys
1672 1
    while (count($path) > 1) {
1673
      $key = \array_shift($path);
1674 1
1675
      // If the key doesn't exist at this depth, we will just create an empty array
1676
      // to hold the next value, allowing us to create the arrays to hold final
1677
      // values at the correct depth. Then we'll keep digging into the array.
1678
      if (!isset($array[$key]) || !is_array($array[$key])) {
1679
        $array[$key] = static::create(array());
1680
      }
1681
1682
      $array =& $array[$key];
1683
    }
1684
1685 1
    $array[\array_shift($path)] = $value;
1686
1687
    return true;
1688 1
  }
1689 1
1690 1
  /**
1691
   * Return an array with all elements found in input array.
1692
   *
1693 1
   * @param array $search
1694 1
   *
1695 1
   * @return static <p>(Immutable)</p>
1696 1
   */
1697
  public function intersection(array $search)
1698
  {
1699 1
    return static::create(\array_values(\array_intersect($this->array, $search)));
1700
  }
1701
1702
  /**
1703
   * Return a boolean flag which indicates whether the two input arrays have any common elements.
1704
   *
1705
   * @param array $search
1706
   *
1707 15
   * @return bool
1708
   */
1709 15
  public function intersects(array $search)
1710 3
  {
1711
    return count($this->intersection($search)->array) > 0;
1712
  }
1713 13
1714 13
  /**
1715 11
   * Invoke a function on all of an array's values.
1716
   *
1717 3
   * @param mixed $callable
1718
   * @param mixed $arguments
1719 3
   *
1720
   * @return static <p>(Immutable)</p>
1721
   */
1722
  public function invoke($callable, $arguments = array())
1723
  {
1724
    // If one argument given for each iteration, create an array for it.
1725
    if (!is_array($arguments)) {
1726
      $arguments = StaticArrayy::repeat($arguments, count($this->array))->getArray();
1727 88
    }
1728
1729 88
    // If the callable has arguments, pass them.
1730
    if ($arguments) {
0 ignored issues
show
Bug Best Practice introduced by
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 empty(..) or ! empty(...) instead.

Loading history...
1731
      $array = \array_map($callable, $this->array, $arguments);
1732
    } else {
1733
      $array = \array_map($callable, $this->array);
1734
    }
1735
1736
    return static::create($array);
1737
  }
1738
1739
  /**
1740
   * Check whether array is associative or not.
1741
   *
1742
   * @return bool <p>Returns true if associative, false otherwise.</p>
1743
   */
1744
  public function isAssoc()
1745
  {
1746
    if ($this->isEmpty()) {
1747
      return false;
1748
    }
1749 14
1750
    foreach ($this->keys()->getArray() as $key) {
1751 14
      if (!is_string($key)) {
1752
        return false;
1753
      }
1754
    }
1755
1756
    return true;
1757
  }
1758
1759 5
  /**
1760
   * Check whether the array is empty or not.
1761 5
   *
1762 2
   * @return bool <p>Returns true if empty, false otherwise.</p>
1763
   */
1764
  public function isEmpty()
1765 4
  {
1766 4
    return !$this->array;
1767 2
  }
1768
1769 3
  /**
1770
   * Check if the current array is equal to the given "$array" or not.
1771 2
   *
1772
   * @param array $array
1773
   *
1774
   * @return bool
1775
   */
1776
  public function isEqual(array $array)
1777
  {
1778
    return ($this->array === $array);
1779 1
  }
1780
1781 1
  /**
1782
   * Check if the current array is a multi-array.
1783
   *
1784
   * @return bool
1785
   */
1786
  public function isMultiArray()
1787
  {
1788
    return !(count($this->array) === count($this->array, COUNT_RECURSIVE));
1789
  }
1790
1791
  /**
1792
   * Check whether array is numeric or not.
1793
   *
1794
   * @return bool <p>Returns true if numeric, false otherwise.</p>
1795
   */
1796
  public function isNumeric()
1797 25
  {
1798
    if ($this->isEmpty()) {
1799 25
      return false;
1800
    }
1801
1802
    foreach ($this->keys() as $key) {
1803
      if (!is_int($key)) {
1804
        return false;
1805
      }
1806
    }
1807
1808
    return true;
1809
  }
1810
1811
  /**
1812
   * Check if the current array is sequential [0, 1, 2, 3, 4, 5 ...] or not.
1813 4
   *
1814
   * @return bool
1815 4
   */
1816
  public function isSequential()
1817 4
  {
1818
    return \array_keys($this->array) === range(0, count($this->array) - 1);
1819
  }
1820
1821
  /**
1822
   * @return array
1823
   */
1824
  public function jsonSerialize()
1825 4
  {
1826
    return $this->getArray();
1827 4
  }
1828
1829
  /**
1830
   * Get all keys from the current array.
1831
   *
1832
   * @return static <p>(Immutable)</p>
1833
   */
1834
  public function keys()
1835
  {
1836
    return static::create(\array_keys($this->array));
1837 13
  }
1838
1839 13
  /**
1840 1
   * Sort an array by key in reverse order.
1841
   *
1842
   * @param int $sort_flags [optional] <p>
1843 12
   *                        You may modify the behavior of the sort using the optional
1844 8
   *                        parameter sort_flags, for details
1845
   *                        see sort.
1846 8
   *                        </p>
1847 1
   *
1848 1
   * @return static <p>(Mutable) Return this Arrayy object.</p>
1849 7
   */
1850
  public function krsort($sort_flags = null)
1851
  {
1852 8
    krsort($this->array, $sort_flags);
1853 8
1854 4
    return $this;
1855 4
  }
1856
1857
  /**
1858 12
   * Get the last value from the current array.
1859
   *
1860
   * @return mixed <p>Return null if there wasn't a element.</p>
1861
   */
1862
  public function last()
1863
  {
1864
    return $this->pop();
1865
  }
1866
1867
  /**
1868 13
   * Get the last value(s) from the current array.
1869
   *
1870 13
   * @param int|null $number
1871 1
   *
1872
   * @return static <p>(Immutable)</p>
1873
   */
1874 12
  public function lastsImmutable($number = null)
1875 8
  {
1876
    if ($this->isEmpty()) {
1877 8
      return static::create();
1878 1
    }
1879 1
1880 7
    if ($number === null) {
1881
      $poppedValue = $this->pop();
1882
1883 8
      if ($poppedValue === null) {
1884 8
        $poppedValue = array($poppedValue);
1885 4
      } else {
1886 4
        $poppedValue = (array)$poppedValue;
1887
      }
1888
1889 12
      $arrayy = static::create($poppedValue);
1890
    } else {
1891
      $number = (int)$number;
1892
      $arrayy = $this->rest(-$number);
1893
    }
1894
1895
    return $arrayy;
1896
  }
1897
1898
  /**
1899
   * Get the last value(s) from the current array.
1900
   *
1901 10
   * @param int|null $number
1902
   *
1903 10
   * @return static <p>(Mutable)</p>
1904
   */
1905
  public function lastsMutable($number = null)
1906
  {
1907
    if ($this->isEmpty()) {
1908
      return $this;
1909
    }
1910
1911
    if ($number === null) {
1912
      $poppedValue = $this->pop();
1913
1914 4
      if ($poppedValue === null) {
1915
        $poppedValue = array($poppedValue);
1916 4
      } else {
1917
        $poppedValue = (array)$poppedValue;
1918 4
      }
1919
1920
      $this->array = static::create($poppedValue)->array;
1921
    } else {
1922
      $number = (int)$number;
1923
      $this->array = $this->rest(-$number)->array;
1924
    }
1925
1926
    return $this;
1927
  }
1928 15
1929
  /**
1930 15
   * Count the values from the current array.
1931 2
   *
1932
   * alias: for "Arrayy->size()"
1933
   *
1934
   * @see Arrayy::size()
1935 13
   *
1936
   * @return int
1937 13
   */
1938 13
  public function length()
1939
  {
1940 13
    return $this->size();
1941 7
  }
1942
1943 9
  /**
1944
   * Apply the given function to the every element of the array,
1945 7
   * collecting the results.
1946
   *
1947
   * @param callable $callable
1948
   *
1949
   * @return static <p>(Immutable) Arrayy object with modified elements.</p>
1950
   */
1951
  public function map($callable)
1952
  {
1953
    $result = \array_map($callable, $this->array);
1954
1955 14
    return static::create($result);
1956
  }
1957 14
1958 2
  /**
1959
   * Check if all items in current array match a truth test.
1960
   *
1961
   * @param \Closure $closure
1962 12
   *
1963
   * @return bool
1964 12
   */
1965 12 View Code Duplication
  public function matches(\Closure $closure)
0 ignored issues
show
Duplication introduced by
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...
1966
  {
1967 12
    if (count($this->array) === 0) {
1968 9
      return false;
1969
    }
1970 5
1971
    // init
1972 4
    $array = $this->array;
1973
1974
    foreach ($array as $key => $value) {
1975
      $value = $closure($value, $key);
1976
1977
      if ($value === false) {
1978
        return false;
1979
      }
1980 10
    }
1981
1982 10
    return true;
1983 1
  }
1984
1985
  /**
1986 9
   * Check if any item in the current array matches a truth test.
1987
   *
1988
   * @param \Closure $closure
1989
   *
1990
   * @return bool
1991
   */
1992 View Code Duplication
  public function matchesAny(\Closure $closure)
0 ignored issues
show
Duplication introduced by
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...
1993
  {
1994
    if (count($this->array) === 0) {
1995
      return false;
1996
    }
1997
1998
    // init
1999 25
    $array = $this->array;
2000
2001 25
    foreach ($array as $key => $value) {
2002 4
      $value = $closure($value, $key);
2003 4
2004 21
      if ($value === true) {
2005
        return true;
2006
      }
2007 25
    }
2008
2009
    return false;
2010
  }
2011
2012
  /**
2013
   * Get the max value from an array.
2014
   *
2015
   * @return mixed
2016
   */
2017
  public function max()
2018
  {
2019
    if ($this->count() === 0) {
2020
      return false;
2021 16
    }
2022
2023 16
    return max($this->array);
2024 4
  }
2025 4
2026 12
  /**
2027
   * Merge the new $array into the current array.
2028
   *
2029 16
   * - keep key,value from the current array, also if the index is in the new $array
2030
   *
2031
   * @param array $array
2032
   * @param bool  $recursive
2033
   *
2034
   * @return static <p>(Immutable)</p>
2035
   */
2036 View Code Duplication
  public function mergeAppendKeepIndex(array $array = array(), $recursive = false)
0 ignored issues
show
Duplication introduced by
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...
2037
  {
2038
    if (true === $recursive) {
2039
      $result = \array_replace_recursive($this->array, $array);
2040
    } else {
2041
      $result = \array_replace($this->array, $array);
2042 16
    }
2043
2044 16
    return static::create($result);
2045 4
  }
2046 4
2047 12
  /**
2048
   * Merge the new $array into the current array.
2049
   *
2050 16
   * - replace duplicate assoc-keys from the current array with the key,values from the new $array
2051
   * - create new indexes
2052
   *
2053
   * @param array $array
2054
   * @param bool  $recursive
2055
   *
2056
   * @return static <p>(Immutable)</p>
2057
   */
2058 View Code Duplication
  public function mergeAppendNewIndex(array $array = array(), $recursive = false)
0 ignored issues
show
Duplication introduced by
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...
2059
  {
2060
    if (true === $recursive) {
2061
      $result = \array_merge_recursive($this->array, $array);
2062
    } else {
2063
      $result = \array_merge($this->array, $array);
2064 17
    }
2065
2066 17
    return static::create($result);
2067 4
  }
2068 4
2069 13
  /**
2070
   * Merge the the current array into the $array.
2071
   *
2072 17
   * - use key,value from the new $array, also if the index is in the current array
2073
   *
2074
   * @param array $array
2075
   * @param bool  $recursive
2076
   *
2077
   * @return static <p>(Immutable)</p>
2078
   */
2079 View Code Duplication
  public function mergePrependKeepIndex(array $array = array(), $recursive = false)
0 ignored issues
show
Duplication introduced by
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...
2080 10
  {
2081
    if (true === $recursive) {
2082 10
      $result = \array_replace_recursive($array, $this->array);
2083 1
    } else {
2084
      $result = \array_replace($array, $this->array);
2085
    }
2086 9
2087
    return static::create($result);
2088
  }
2089
2090
  /**
2091
   * Merge the current array into the new $array.
2092
   *
2093
   * - replace duplicate assoc-keys from new $array with the key,values from the current array
2094
   * - create new indexes
2095
   *
2096
   * @param array $array
2097
   * @param bool  $recursive
2098
   *
2099 1
   * @return static <p>(Immutable)</p>
2100
   */
2101 1 View Code Duplication
  public function mergePrependNewIndex(array $array = array(), $recursive = false)
0 ignored issues
show
Duplication introduced by
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...
2102
  {
2103 1
    if (true === $recursive) {
2104 1
      $result = \array_merge_recursive($array, $this->array);
2105 1
    } else {
2106 1
      $result = \array_merge($array, $this->array);
2107 1
    }
2108 1
2109 1
    return static::create($result);
2110 1
  }
2111 1
2112 1
  /**
2113 1
   * Get the min value from an array.
2114 1
   *
2115 1
   * @return mixed
2116 1
   */
2117 1
  public function min()
2118 1
  {
2119 1
    if ($this->count() === 0) {
2120 1
      return false;
2121
    }
2122
2123
    return min($this->array);
2124 1
  }
2125
2126
  /**
2127
   * Move an array element to a new index.
2128
   *
2129
   * cherry-picked from: http://stackoverflow.com/questions/12624153/move-an-array-element-to-a-new-index-in-php
2130
   *
2131
   * @param int|string $from
2132
   * @param int|string $to
2133
   *
2134
   * @return static <p>(Immutable)</p>
2135
   */
2136
  public function moveElement($from, $to)
2137
  {
2138
    $array = $this->array;
2139
2140
    if (is_int($from)) {
2141
      $tmp = \array_splice($array, $from, 1);
2142
      \array_splice($array, $to, 0, $tmp);
2143
      $output = $array;
2144
    } elseif (is_string($from)) {
2145
      $indexToMove = \array_search($from, \array_keys($array), true);
2146
      $itemToMove = $array[$from];
2147
      \array_splice($array, $indexToMove, 1);
2148
      $i = 0;
2149 4
      $output = array();
2150
      foreach ($array as $key => $item) {
2151 4
        if ($i == $to) {
2152
          $output[$from] = $itemToMove;
2153 4
        }
2154
        $output[$key] = $item;
2155
        $i++;
2156
      }
2157
    } else {
2158
      $output = array();
2159
    }
2160
2161 16
    return static::create($output);
2162
  }
2163 16
2164
  /**
2165
   * Get a subset of the items from the given array.
2166
   *
2167
   * @param mixed[] $keys
2168
   *
2169
   * @return static <p>(Immutable)</p>
2170
   */
2171
  public function only(array $keys)
2172
  {
2173
    $array = $this->array;
2174 8
2175
    return static::create(\array_intersect_key($array, \array_flip($keys)));
2176 8
  }
2177 8
2178 8
  /**
2179
   * Pad array to the specified size with a given value.
2180 1
   *
2181
   * @param int   $size  <p>Size of the result array.</p>
2182
   * @param mixed $value <p>Empty value by default.</p>
2183 8
   *
2184
   * @return static <p>(Immutable) Arrayy object padded to $size with $value.</p>
2185
   */
2186
  public function pad($size, $value)
2187
  {
2188
    $result = \array_pad($this->array, $size, $value);
2189
2190
    return static::create($result);
2191 4
  }
2192
2193 4
  /**
2194 4
   * Pop a specified value off the end of the current array.
2195 4
   *
2196 4
   * @return mixed <p>(Mutable) The popped element from the current array.</p>
2197
   */
2198 4
  public function pop()
2199
  {
2200
    return \array_pop($this->array);
2201
  }
2202
2203
  /**
2204
   * Prepend a value to the current array.
2205
   *
2206
   * @param mixed $value
2207
   * @param mixed $key
2208 17
   *
2209
   * @return static <p>(Mutable) Return this Arrayy object, with the prepended value.</p>
2210 17
   */
2211
  public function prepend($value, $key = null)
2212
  {
2213
    if ($key === null) {
2214 17
      \array_unshift($this->array, $value);
2215 14
    } else {
2216
      /** @noinspection AdditionOperationOnArraysInspection */
2217 14
      $this->array = array($key => $value) + $this->array;
2218
    }
2219
2220 5
    return $this;
2221 5
  }
2222
2223 5
  /**
2224
   * Push one or more values onto the end of array at once.
2225
   *
2226
   * @return static <p>(Mutable) Return this Arrayy object, with pushed elements to the end of array.</p>
2227
   */
2228 View Code Duplication
  public function push(/* variadic arguments allowed */)
0 ignored issues
show
Duplication introduced by
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...
2229
  {
2230
    if (func_num_args()) {
2231
      $args = \array_merge(array(&$this->array), func_get_args());
2232
      call_user_func_array('array_push', $args);
2233 4
    }
2234
2235 4
    return $this;
2236
  }
2237 4
2238
  /**
2239
   * Get a random value from the current array.
2240
   *
2241 4
   * @param null|int $number <p>How many values you will take?</p>
2242
   *
2243
   * @return static <p>(Immutable)</p>
2244
   */
2245
  public function randomImmutable($number = null)
2246
  {
2247
    if ($this->count() === 0) {
2248
      return static::create();
2249
    }
2250
2251 View Code Duplication
    if ($number === null) {
0 ignored issues
show
Duplication introduced by
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...
2252
      $arrayRandValue = array($this->array[\array_rand($this->array)]);
2253 14
2254
      return static::create($arrayRandValue);
2255 14
    }
2256 14
2257
    $arrayTmp = $this->array;
2258 14
    shuffle($arrayTmp);
2259 3
2260 3
    return static::create($arrayTmp)->firstsImmutable($number);
2261 3
  }
2262 3
2263
  /**
2264 3
   * Pick a random key/index from the keys of this array.
2265 3
   *
2266
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
2267
   *
2268 11
   * @throws \RangeException If array is empty
2269
   */
2270 11
  public function randomKey()
2271
  {
2272
    $result = $this->randomKeys(1);
2273
2274
    if (!isset($result[0])) {
2275
      $result[0] = null;
2276
    }
2277
2278
    return $result[0];
2279
  }
2280 17
2281
  /**
2282 17
   * Pick a given number of random keys/indexes out of this array.
2283
   *
2284
   * @param int $number <p>The number of keys/indexes (should be <= $this->count())</p>
2285
   *
2286 17
   * @return static <p>(Immutable)</p>
2287 7
   *
2288 7
   * @throws \RangeException If array is empty
2289
   */
2290 7
  public function randomKeys($number)
2291
  {
2292
    $number = (int)$number;
2293 11
    $count = $this->count();
2294
2295 11
    if ($number === 0 || $number > $count) {
2296
      throw new \RangeException(
2297
          sprintf(
2298
              'Number of requested keys (%s) must be equal or lower than number of elements in this array (%s)',
2299
              $number,
2300
              $count
2301
          )
2302
      );
2303 4
    }
2304
2305 4
    $result = (array)\array_rand($this->array, $number);
2306
2307 4
    return static::create($result);
2308
  }
2309
2310
  /**
2311 4
   * Get a random value from the current array.
2312
   *
2313
   * @param null|int $number <p>How many values you will take?</p>
2314
   *
2315
   * @return static <p>(Mutable)</p>
2316
   */
2317
  public function randomMutable($number = null)
2318
  {
2319
    if ($this->count() === 0) {
2320
      return static::create();
2321 7
    }
2322
2323 7 View Code Duplication
    if ($number === null) {
0 ignored issues
show
Duplication introduced by
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...
2324
      $arrayRandValue = array($this->array[\array_rand($this->array)]);
2325 7
      $this->array = $arrayRandValue;
2326
2327
      return $this;
2328
    }
2329
2330
    shuffle($this->array);
2331
2332
    return $this->firstsMutable($number);
2333
  }
2334
2335
  /**
2336
   * Pick a random value from the values of this array.
2337
   *
2338 9
   * @return mixed <p>Get a random value or null if there wasn't a value.</p>
2339
   */
2340 9
  public function randomValue()
2341 9
  {
2342 9
    $result = $this->randomImmutable();
2343 2
2344 1
    if (!isset($result[0])) {
2345 1
      $result[0] = null;
2346 2
    }
2347 9
2348
    return $result[0];
2349 9
  }
2350
2351
  /**
2352
   * Pick a given number of random values out of this array.
2353
   *
2354
   * @param int $number
2355
   *
2356
   * @return static <p>(Mutable)</p>
2357
   */
2358
  public function randomValues($number)
2359
  {
2360 4
    $number = (int)$number;
2361
2362 4
    return $this->randomMutable($number);
2363
  }
2364 4
2365
  /**
2366
   * Get a random value from an array, with the ability to skew the results.
2367 4
   *
2368
   * Example: randomWeighted(['foo' => 1, 'bar' => 2]) has a 66% chance of returning bar.
2369
   *
2370 4
   * @param array    $array
2371
   * @param null|int $number <p>How many values you will take?</p>
2372
   *
2373
   * @return static <p>(Immutable)</p>
2374
   */
2375
  public function randomWeighted(array $array, $number = null)
2376
  {
2377
    $options = array();
2378 9
    foreach ($array as $option => $weight) {
2379
      if ($this->searchIndex($option) !== false) {
2380 9
        for ($i = 0; $i < $weight; ++$i) {
2381
          $options[] = $option;
2382 9
        }
2383
      }
2384
    }
2385
2386
    return $this->mergeAppendKeepIndex($options)->randomImmutable($number);
2387
  }
2388
2389
  /**
2390
   * Reduce the current array via callable e.g. anonymous-function.
2391
   *
2392 1
   * @param mixed $callable
2393
   * @param array $init
2394 1
   *
2395
   * @return static <p>(Immutable)</p>
2396 1
   */
2397 1
  public function reduce($callable, array $init = array())
2398 1
  {
2399 1
    $result = \array_reduce($this->array, $callable, $init);
2400 1
2401
    if ($result === null) {
2402 1
      $this->array = array();
2403
    } else {
2404
      $this->array = (array)$result;
2405
    }
2406
2407
    return static::create($this->array);
2408
  }
2409
2410
  /**
2411
   * Create a numerically re-indexed Arrayy object.
2412 18
   *
2413
   * @return static <p>(Mutable) Return this Arrayy object, with re-indexed array-elements.</p>
2414
   */
2415 18
  public function reindex()
2416
  {
2417
    $this->array = \array_values($this->array);
2418
2419
    return $this;
2420
  }
2421
2422
  /**
2423 18
   * Return all items that fail the truth test.
2424
   *
2425 18
   * @param \Closure $closure
2426
   *
2427
   * @return static <p>(Immutable)</p>
2428
   */
2429 View Code Duplication
  public function reject(\Closure $closure)
0 ignored issues
show
Duplication introduced by
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...
2430
  {
2431
    $filtered = array();
2432
2433 7
    foreach ($this->array as $key => $value) {
2434
      if (!$closure($value, $key)) {
2435 7
        $filtered[$key] = $value;
2436 7
      }
2437
    }
2438 7
2439
    return static::create($filtered);
2440
  }
2441
2442
  /**
2443
   * Remove a value from the current array (optional using dot-notation).
2444
   *
2445
   * @param mixed $key
2446 7
   *
2447
   * @return static <p>(Immutable)</p>
2448 7
   */
2449 7
  public function remove($key)
2450
  {
2451 7
    // Recursive call
2452
    if (is_array($key)) {
2453
      foreach ($key as $k) {
2454
        $this->internalRemove($k);
2455
      }
2456
2457
      return static::create($this->array);
2458
    }
2459
2460
    $this->internalRemove($key);
2461 7
2462
    return static::create($this->array);
2463 7
  }
2464 7
2465 6
  /**
2466 6
   * Remove the first value from the current array.
2467
   *
2468
   * @return static <p>(Immutable)</p>
2469 6
   */
2470 6
  public function removeFirst()
2471 7
  {
2472
    $tmpArray = $this->array;
2473 7
    \array_shift($tmpArray);
2474 7
2475 7
    return static::create($tmpArray);
2476
  }
2477 7
2478
  /**
2479
   * Remove the last value from the current array.
2480
   *
2481
   * @return static <p>(Immutable)</p>
2482
   */
2483
  public function removeLast()
2484
  {
2485
    $tmpArray = $this->array;
2486
    \array_pop($tmpArray);
2487 1
2488
    return static::create($tmpArray);
2489 1
  }
2490 1
2491
  /**
2492
   * Removes a particular value from an array (numeric or associative).
2493 1
   *
2494
   * @param mixed $value
2495
   *
2496
   * @return static <p>(Immutable)</p>
2497
   */
2498
  public function removeValue($value)
2499
  {
2500
    $isNumericArray = true;
2501
    foreach ($this->array as $key => $item) {
2502
      if ($item === $value) {
2503
        if (!is_int($key)) {
2504
          $isNumericArray = false;
2505 2
        }
2506
        unset($this->array[$key]);
2507 2
      }
2508
    }
2509 2
2510
    if ($isNumericArray) {
2511
      $this->array = \array_values($this->array);
2512
    }
2513
2514
    return static::create($this->array);
2515
  }
2516
2517
  /**
2518
   * Generate array of repeated arrays.
2519 2
   *
2520
   * @param int $times <p>How many times has to be repeated.</p>
2521 2
   *
2522
   * @return Arrayy
2523 2
   */
2524
  public function repeat($times)
2525
  {
2526
    if ($times === 0) {
2527
      return new static();
2528
    }
2529
2530
    return static::create(\array_fill(0, (int)$times, $this->array));
2531
  }
2532
2533 2
  /**
2534
   * Replace a key with a new key/value pair.
2535 2
   *
2536
   * @param $replace
2537 2
   * @param $key
2538
   * @param $value
2539
   *
2540
   * @return static <p>(Immutable)</p>
2541
   */
2542
  public function replace($replace, $key, $value)
2543
  {
2544
    $this->remove($replace);
2545
2546
    return $this->set($key, $value);
2547 1
  }
2548
2549 1
  /**
2550 1
   * Create an array using the current array as values and the other array as keys.
2551
   *
2552 1
   * @param array $keys <p>An array of keys.</p>
2553
   *
2554
   * @return static <p>(Immutable) Arrayy object with keys from the other array.</p>
2555
   */
2556
  public function replaceAllKeys(array $keys)
2557
  {
2558
    $result = \array_combine($keys, $this->array);
2559
2560
    return static::create($result);
2561
  }
2562
2563 3
  /**
2564
   * Create an array using the current array as keys and the other array as values.
2565 3
   *
2566 3
   * @param array $array <p>An array o values.</p>
2567
   *
2568 3
   * @return static <p>(Immutable) Arrayy object with values from the other array.</p>
2569 3
   */
2570 3
  public function replaceAllValues(array $array)
2571
  {
2572 3
    $result = \array_combine($this->array, $array);
2573
2574
    return static::create($result);
2575
  }
2576
2577
  /**
2578
   * Replace the keys in an array with another set.
2579
   *
2580
   * @param array $keys <p>An array of keys matching the array's size</p>
2581
   *
2582
   * @return static <p>(Immutable)</p>
2583 1
   */
2584
  public function replaceKeys(array $keys)
2585 1
  {
2586
    $values = \array_values($this->array);
2587 1
    $result = \array_combine($keys, $values);
2588
2589 1
    return static::create($result);
2590
  }
2591 1
2592
  /**
2593
   * Replace the first matched value in an array.
2594
   *
2595
   * @param mixed $search
2596
   * @param mixed $replacement
2597
   *
2598
   * @return static <p>(Immutable)</p>
2599
   */
2600
  public function replaceOneValue($search, $replacement = '')
2601 15
  {
2602
    $array = $this->array;
2603 15
    $key = \array_search($search, $array, true);
2604
2605 15
    if ($key !== false) {
2606
      $array[$key] = $replacement;
2607
    }
2608
2609
    return static::create($array);
2610
  }
2611
2612
  /**
2613 8
   * Replace values in the current array.
2614
   *
2615 8
   * @param string $search      <p>The string to replace.</p>
2616
   * @param string $replacement <p>What to replace it with.</p>
2617 8
   *
2618
   * @return static <p>(Immutable)</p>
2619
   */
2620
  public function replaceValues($search, $replacement = '')
2621
  {
2622
    $array = $this->each(
2623
        function ($value) use ($search, $replacement) {
2624
          return UTF8::str_replace($search, $replacement, $value);
2625
        }
2626
    );
2627
2628
    return $array;
2629
  }
2630
2631 4
  /**
2632
   * Get the last elements from index $from until the end of this array.
2633 4
   *
2634
   * @param int $from
2635 4
   *
2636
   * @return static <p>(Immutable)</p>
2637
   */
2638
  public function rest($from = 1)
2639
  {
2640
    $tmpArray = $this->array;
2641
2642
    return static::create(\array_splice($tmpArray, $from));
2643
  }
2644
2645 20
  /**
2646
   * Return the array in the reverse order.
2647 20
   *
2648
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2649
   */
2650
  public function reverse()
2651
  {
2652
    $this->array = \array_reverse($this->array);
2653
2654
    return $this;
2655
  }
2656
2657 9
  /**
2658
   * Sort an array in reverse order.
2659
   *
2660 9
   * @param int $sort_flags [optional] <p>
2661
   *                        You may modify the behavior of the sort using the optional
2662 9
   *                        parameter sort_flags, for details
2663
   *                        see sort.
2664
   *                        </p>
2665
   *
2666
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2667 9
   */
2668 1
  public function rsort($sort_flags = null)
2669 1
  {
2670
    rsort($this->array, $sort_flags);
2671 9
2672 7
    return $this;
2673 7
  }
2674
2675
  /**
2676 9
   * Search for the first index of the current array via $value.
2677
   *
2678
   * @param mixed $value
2679
   *
2680
   * @return int|float|string
2681
   */
2682
  public function searchIndex($value)
2683
  {
2684
    return \array_search($value, $this->array, true);
2685
  }
2686
2687 17
  /**
2688
   * Search for the value of the current array via $index.
2689 17
   *
2690
   * @param mixed $index
2691 17
   *
2692
   * @return static <p>(Immutable) Will return a empty Arrayy if the value wasn't found.</p>
2693
   */
2694
  public function searchValue($index)
2695
  {
2696
    // init
2697
    $return = array();
2698
2699
    if ($this->isEmpty()) {
2700
      return static::create();
2701
    }
2702
2703
    // php cast "bool"-index into "int"-index
2704 11
    if ((bool)$index === $index) {
2705
      $index = (int)$index;
2706
    }
2707 11
2708 4
    if (\array_key_exists($index, $this->array) === true) {
2709 4
      $return = array($this->array[$index]);
2710
    }
2711 11
2712
2713
    return static::create($return);
2714
  }
2715
2716
  /**
2717
   * Set a value for the current array (optional using dot-notation).
2718
   *
2719 4
   * @param string $key   <p>The key to set.</p>
2720
   * @param mixed  $value <p>Its value.</p>
2721 4
   *
2722
   * @return static <p>(Immutable)</p>
2723
   */
2724
  public function set($key, $value)
2725
  {
2726
    $this->internalSet($key, $value);
2727
2728
    return static::create($this->array);
2729 1
  }
2730
2731 1
  /**
2732
   * Get a value from a array and set it if it was not.
2733 1
   *
2734
   * WARNING: this method only set the value, if the $key is not already set
2735 1
   *
2736
   * @param string $key      <p>The key</p>
2737
   * @param mixed  $fallback <p>The default value to set if it isn't.</p>
2738
   *
2739
   * @return mixed <p>(Mutable)</p>
2740
   */
2741
  public function setAndGet($key, $fallback = null)
2742
  {
2743 93
    // If the key doesn't exist, set it.
2744
    if (!$this->has($key)) {
2745 93
      $this->array = $this->set($key, $fallback)->getArray();
2746
    }
2747
2748
    return $this->get($key);
2749
  }
2750
2751
  /**
2752
   * Shifts a specified value off the beginning of array.
2753
   *
2754
   * @return mixed <p>(Mutable) A shifted element from the current array.</p>
2755
   */
2756
  public function shift()
2757 4
  {
2758
    return \array_shift($this->array);
2759 4
  }
2760
2761 4
  /**
2762
   * Shuffle the current array.
2763
   *
2764
   * @return static <p>(Immutable)</p>
2765
   */
2766
  public function shuffle()
2767
  {
2768
    $array = $this->array;
2769
2770
    shuffle($array);
2771
2772
    return static::create($array);
2773
  }
2774 19
2775
  /**
2776 19
   * Get the size of an array.
2777
   *
2778 19
   * @return int
2779
   */
2780
  public function size()
2781
  {
2782
    return count($this->array);
2783
  }
2784
2785
  /**
2786
   * Extract a slice of the array.
2787
   *
2788
   * @param int      $offset       <p>Slice begin index.</p>
2789
   * @param int|null $length       <p>Length of the slice.</p>
2790
   * @param bool     $preserveKeys <p>Whether array keys are preserved or no.</p>
2791
   *
2792
   * @return static <p>A slice of the original array with length $length.</p>
2793 18
   */
2794
  public function slice($offset, $length = null, $preserveKeys = false)
2795 18
  {
2796
    $result = \array_slice($this->array, $offset, $length, $preserveKeys);
2797 18
2798
    return static::create($result);
2799
  }
2800
2801
  /**
2802
   * Sort the current array and optional you can keep the keys.
2803
   *
2804
   * @param integer $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2805
   * @param integer $strategy  <p>sort_flags => use e.g.: <strong>SORT_REGULAR</strong> (default) or
2806
   *                           <strong>SORT_NATURAL</strong></p>
2807
   * @param bool    $keepKeys
2808 1
   *
2809
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2810 1
   */
2811
  public function sort($direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2812
  {
2813
    $this->sorting($this->array, $direction, $strategy, $keepKeys);
2814
2815
    return $this;
2816
  }
2817
2818
  /**
2819
   * Sort the current array by key.
2820
   *
2821 1
   * @link http://php.net/manual/en/function.ksort.php
2822
   * @link http://php.net/manual/en/function.krsort.php
2823 1
   *
2824
   * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2825
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2826
   *                              <strong>SORT_NATURAL</strong></p>
2827
   *
2828
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2829
   */
2830
  public function sortKeys($direction = SORT_ASC, $strategy = SORT_REGULAR)
2831
  {
2832
    $this->sorterKeys($this->array, $direction, $strategy);
2833
2834
    return $this;
2835
  }
2836
2837
  /**
2838
   * Sort the current array by value.
2839 1
   *
2840
   * @param int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2841 1
   * @param int $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2842 1
   *
2843
   * @return static <p>(Mutable)</p>
2844
   */
2845 1
  public function sortValueKeepIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2846 1
  {
2847
    return $this->sort($direction, $strategy, true);
2848 1
  }
2849 1
2850
  /**
2851 1
   * Sort the current array by value.
2852
   *
2853 1
   * @param int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2854
   * @param int $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2855 1
   *
2856 1
   * @return static <p>(Mutable)</p>
2857 1
   */
2858
  public function sortValueNewIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2859
  {
2860
    return $this->sort($direction, $strategy, false);
2861 1
  }
2862
2863 1
  /**
2864
   * Sort a array by value, by a closure or by a property.
2865
   *
2866
   * - If the sorter is null, the array is sorted naturally.
2867
   * - Associative (string) keys will be maintained, but numeric keys will be re-indexed.
2868
   *
2869
   * @param null       $sorter
2870
   * @param string|int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2871
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2872
   *                              <strong>SORT_NATURAL</strong></p>
2873
   *
2874
   * @return static <p>(Immutable)</p>
2875 18
   */
2876
  public function sorter($sorter = null, $direction = SORT_ASC, $strategy = SORT_REGULAR)
2877 18
  {
2878
    $array = (array)$this->array;
2879
    $direction = $this->getDirection($direction);
2880 18
2881 18
    // Transform all values into their results.
2882 6
    if ($sorter) {
2883 6
      $arrayy = static::create($array);
2884 13
2885 13
      $that = $this;
2886 13
      $results = $arrayy->each(
2887 13
          function ($value) use ($sorter, $that) {
2888 13
            return is_callable($sorter) ? $sorter($value) : $that->get($sorter, null, $value);
2889
          }
2890 18
      );
2891
2892
      $results = $results->getArray();
2893
    } else {
2894
      $results = $array;
2895
    }
2896
2897
    // Sort by the results and replace by original values
2898
    \array_multisort($results, $direction, $strategy, $array);
2899
2900
    return static::create($array);
2901
  }
2902 19
2903
  /**
2904 19
   * sorting keys
2905
   *
2906 19
   * @param array $elements
2907 19
   * @param int   $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2908 19
   * @param int   $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2909
   *
2910
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2911 19
   */
2912 19
  protected function sorterKeys(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR)
2913 9
  {
2914 5
    $direction = $this->getDirection($direction);
2915 5
2916 4
    switch ($direction) {
2917
      case 'desc':
2918 9
      case SORT_DESC:
2919 10
        krsort($elements, $strategy);
2920 10
        break;
2921 10
      case 'asc':
2922 10
      case SORT_ASC:
2923 4
      default:
2924 4
        ksort($elements, $strategy);
2925 6
    }
2926
2927 10
    return $this;
2928
  }
2929 19
2930
  /**
2931
   * @param array      &$elements
2932
   * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2933
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2934
   *                              <strong>SORT_NATURAL</strong></p>
2935
   * @param bool       $keepKeys
2936
   *
2937
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2938
   */
2939
  protected function sorting(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2940 1
  {
2941
    $direction = $this->getDirection($direction);
2942 1
2943
    if (!$strategy) {
2944 1
      $strategy = SORT_REGULAR;
2945 1
    }
2946 1
2947 1
    switch ($direction) {
2948 1
      case 'desc':
2949 1
      case SORT_DESC:
2950
        if ($keepKeys) {
2951
          arsort($elements, $strategy);
2952 1
        } else {
2953
          rsort($elements, $strategy);
2954
        }
2955
        break;
2956
      case 'asc':
2957
      case SORT_ASC:
2958
      default:
2959
        if ($keepKeys) {
2960 1
          asort($elements, $strategy);
2961
        } else {
2962 1
          sort($elements, $strategy);
2963
        }
2964 1
    }
2965 1
2966
    return $this;
2967
  }
2968 1
2969
  /**
2970 1
   * Split an array in the given amount of pieces.
2971
   *
2972
   * @param int  $numberOfPieces
2973
   * @param bool $keepKeys
2974
   *
2975
   * @return static <p>(Immutable)</p>
2976
   */
2977
  public function split($numberOfPieces = 2, $keepKeys = false)
2978
  {
2979
    $arrayCount = $this->count();
2980
2981 1
    if ($arrayCount === 0) {
2982
      $result = array();
2983 1
    } else {
2984
      $numberOfPieces = (int)$numberOfPieces;
2985 1
      $splitSize = (int)ceil($arrayCount / $numberOfPieces);
2986
      $result = \array_chunk($this->array, $splitSize, $keepKeys);
2987 1
    }
2988
2989
    return static::create($result);
2990
  }
2991
2992
  /**
2993
   * Stripe all empty items.
2994
   *
2995 142
   * @return static <p>(Immutable)</p>
2996
   */
2997 142
  public function stripEmpty()
2998
  {
2999
    return $this->filter(
3000
        function ($item) {
3001
          if ($item === null) {
3002
            return false;
3003
          }
3004
3005
          return (bool)trim((string)$item);
3006
        }
3007
    );
3008 6
  }
3009
3010 6
  /**
3011
   * Swap two values between positions by key.
3012
   *
3013
   * @param string|int $swapA <p>a key in the array</p>
3014
   * @param string|int $swapB <p>a key in the array</p>
3015
   *
3016
   * @return static <p>(Immutable)</p>
3017
   */
3018
  public function swap($swapA, $swapB)
3019
  {
3020 19
    $array = $this->array;
3021
3022 19
    list($array[$swapA], $array[$swapB]) = array($array[$swapB], $array[$swapA]);
3023
3024
    return static::create($array);
3025
  }
3026
3027
  /**
3028
   * alias: for "Arrayy->getArray()"
3029
   *
3030 9
   * @see Arrayy::getArray()
3031
   */
3032 9
  public function toArray()
3033 9
  {
3034
    return $this->getArray();
3035 8
  }
3036 8
3037 8
  /**
3038
   * Convert the current array to JSON.
3039 8
   *
3040 9
   * @param null|int $options [optional] <p>e.g. JSON_PRETTY_PRINT</p>
3041 9
   * @param int      $depth   [optional] <p>Set the maximum depth. Must be greater than zero.</p>
3042 9
   *
3043
   * @return string
3044 9
   */
3045
  public function toJson($options = null, $depth = 512)
3046
  {
3047 9
    return UTF8::json_encode($this->array, $options, $depth);
3048
  }
3049
3050 9
  /**
3051
   * Implodes array to a string with specified separator.
3052
   *
3053
   * @param string $separator [optional] <p>The element's separator.</p>
3054
   *
3055
   * @return string <p>The string representation of array, separated by ",".</p>
3056
   */
3057
  public function toString($separator = ',')
3058 9
  {
3059
    return $this->implode($separator);
3060
  }
3061 9
3062
  /**
3063 9
   * Return a duplicate free copy of the current array.
3064 9
   *
3065 9
   * @return static <p>(Mutable)</p>
3066 8
   */
3067 8
  public function unique()
3068 8
  {
3069
    // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array
3070 8
3071 9
    $this->array = \array_reduce(
0 ignored issues
show
Documentation Bug introduced by
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...
3072 9
        $this->array,
3073 9
        function ($resultArray, $value) {
3074
          if (!in_array($value, $resultArray, true)) {
3075 9
            $resultArray[] = $value;
3076
          }
3077
3078 9
          return $resultArray;
3079
        },
3080
        array()
3081 9
    );
3082
3083 View Code Duplication
    if ($this->array === null) {
0 ignored issues
show
Duplication introduced by
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...
3084
      $this->array = array();
3085
    } else {
3086
      $this->array = (array)$this->array;
3087
    }
3088
3089
    return $this;
3090
  }
3091 9
3092
  /**
3093 9
   * Return a duplicate free copy of the current array. (with the old keys)
3094
   *
3095
   * @return static <p>(Mutable)</p>
3096
   */
3097
  public function uniqueKeepIndex()
3098
  {
3099
    // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array
3100
3101 4
    // init
3102
    $array = $this->array;
3103 4
3104 4
    $this->array = \array_reduce(
0 ignored issues
show
Documentation Bug introduced by
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...
3105 4
        \array_keys($array),
3106 4
        function ($resultArray, $key) use ($array) {
3107
          if (!in_array($array[$key], $resultArray, true)) {
3108 4
            $resultArray[$key] = $array[$key];
3109
          }
3110
3111
          return $resultArray;
3112
        },
3113
        array()
3114
    );
3115
3116 2 View Code Duplication
    if ($this->array === null) {
0 ignored issues
show
Duplication introduced by
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...
3117
      $this->array = array();
3118 2
    } else {
3119
      $this->array = (array)$this->array;
3120
    }
3121
3122
    return $this;
3123
  }
3124
3125
  /**
3126
   * alias: for "Arrayy->unique()"
3127
   *
3128
   * @see Arrayy::unique()
3129 9
   *
3130
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
3131 9
   */
3132 4
  public function uniqueNewIndex()
3133 4
  {
3134 5
    return $this->unique();
3135
  }
3136
3137 9
  /**
3138
   * Prepends one or more values to the beginning of array at once.
3139
   *
3140
   * @return static <p>(Mutable) Return this Arrayy object, with prepended elements to the beginning of array.</p>
3141
   */
3142 View Code Duplication
  public function unshift(/* variadic arguments allowed */)
0 ignored issues
show
Duplication introduced by
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...
3143
  {
3144
    if (func_num_args()) {
3145
      $args = \array_merge(array(&$this->array), func_get_args());
3146
      call_user_func_array('array_unshift', $args);
3147
    }
3148
3149
    return $this;
3150
  }
3151
3152
  /**
3153
   * Get all values from a array.
3154
   *
3155
   * @return static <p>(Immutable)</p>
3156
   */
3157
  public function values()
3158
  {
3159
    return static::create(\array_values((array)$this->array));
3160
  }
3161
3162
  /**
3163
   * Apply the given function to every element in the array, discarding the results.
3164
   *
3165
   * @param callable $callable
3166
   * @param bool     $recursive <p>Whether array will be walked recursively or no</p>
3167
   *
3168
   * @return static <p>(Mutable) Return this Arrayy object, with modified elements.</p>
3169
   */
3170
  public function walk($callable, $recursive = false)
3171
  {
3172
    if (true === $recursive) {
3173
      \array_walk_recursive($this->array, $callable);
3174
    } else {
3175
      \array_walk($this->array, $callable);
3176
    }
3177
3178
    return $this;
3179
  }
3180
}
3181