Completed
Push — master ( b105b3...c4987f )
by Lars
02:20
created

Arrayy::filter()   C

Complexity

Conditions 11
Paths 6

Size

Total Lines 41
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 16.0207

Importance

Changes 0
Metric Value
cc 11
eloc 18
nc 6
nop 2
dl 0
loc 41
ccs 17
cts 26
cp 0.6538
crap 16.0207
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Arrayy;
4
5
use voku\helper\Bootup;
6
use voku\helper\UTF8;
7
8
/** @noinspection ClassReImplementsParentInterfaceInspection */
9
10
/**
11
 * Methods to manage arrays.
12
 *
13
 * For the full copyright and license information, please view the LICENSE
14
 * file that was distributed with this source code.
15
 */
16
class Arrayy extends \ArrayObject implements \IteratorAggregate, \ArrayAccess, \Serializable, \Countable
17
{
18
  /**
19
   * @var array
20
   */
21
  protected $array = array();
22
23
  /**
24
   * @var string
25
   */
26
  protected $iteratorClass;
27
28
  /**
29
   * @var string
30
   */
31
  protected $pathSeparator = '.';
32
33
  /** @noinspection MagicMethodsValidityInspection */
34
  /**
35
   * Initializes
36
   *
37
   * @param array  $array
38
   * @param string $iteratorClass
39 768
   */
40
  public function __construct($array = array(), $iteratorClass = '\\Arrayy\\ArrayyIterator')
41 768
  {
42 766
    $array = $this->fallbackForArray($array);
43
    $this->array = $array;
44 766
45 766
    $this->setIteratorClass($iteratorClass);
46
  }
47
48
  /**
49
   * Get a value by key.
50
   *
51
   * @param $key
52
   *
53
   * @return mixed <p>Get a Value from the current array.</p>
54 2
   */
55
  public function &__get($key)
56 2
  {
57
    $return = $this->get($key);
58 2
59
    if (is_array($return)) {
60
      return static::create($return);
61
    }
62 2
63
    return $return;
64
  }
65
66
  /**
67
   * Call object as function.
68
   *
69
   * @param mixed $key
70
   *
71
   * @return mixed
72 1
   */
73
  public function __invoke($key = null)
74 1
  {
75 1
    if ($key !== null) {
76 1
      if (isset($this->array[$key])) {
77
        return $this->array[$key];
78
      }
79
80
      return false;
81
    }
82
83
    return (array)$this->array;
84
  }
85
86
  /**
87
   * Whether or not an element exists by key.
88
   *
89
   * @param mixed $key
90
   *
91
   * @return bool <p>True is the key/index exists, otherwise false.</p>
92
   */
93
  public function __isset($key)
94
  {
95
    return $this->offsetExists($key);
96
  }
97
98
  /**
99
   * Assigns a value to the specified element.
100
   *
101
   * @param mixed $key
102
   * @param mixed $value
103 2
   */
104
  public function __set($key, $value)
105 2
  {
106 2
    $this->internalSet($key, $value);
107
  }
108
109
  /**
110
   * magic to string
111
   *
112
   * @return string
113 16
   */
114
  public function __toString()
115 16
  {
116
    return $this->toString();
117
  }
118
119
  /**
120
   * Unset element by key.
121
   *
122
   * @param mixed $key
123
   */
124
  public function __unset($key)
125
  {
126
    $this->internalRemove($key);
127
  }
128
129
  /**
130
   * alias: for "Arrayy->append()"
131
   *
132
   * @see Arrayy::append()
133
   *
134
   * @param mixed $value
135
   *
136
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
137 1
   */
138
  public function add($value)
139 1
  {
140
    return $this->append($value);
141
  }
142
143
  /**
144
   * Append a value to the current array.
145
   *
146
   * @param mixed $value
147
   *
148
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
149 9
   */
150
  public function append($value)
151 9
  {
152
    $this->array[] = $value;
153 9
154
    return $this;
155
  }
156
157
  /**
158
   * Sort the entries by value.
159
   *
160
   * @param int $sort_flags [optional] <p>
161
   *                        You may modify the behavior of the sort using the optional
162
   *                        parameter sort_flags, for details
163
   *                        see sort.
164
   *                        </p>
165
   *
166
   * @return static <p>(Mutable) Return this Arrayy object.</p>
167 4
   */
168
  public function asort($sort_flags = null)
169 4
  {
170
    asort($this->array, $sort_flags);
171 4
172
    return $this;
173
  }
174
175
  /**
176
   * Count the values from the current array.
177
   *
178
   * alias: for "Arrayy->size()"
179
   *
180
   * @see Arrayy::size()
181
   *
182
   * @return int
183 93
   */
184
  public function count()
185 93
  {
186
    return $this->size();
187
  }
188
189
  /**
190
   * Counts all the values of an array
191
   *
192
   * @link http://php.net/manual/en/function.array-count-values.php
193
   *
194
   * @return static <p>
195 1
   *                (Immutable)
196
   *                An associative Arrayy-object of values from input as
197 1
   *                keys and their count as value.
198
   *                </p>
199 1
   */
200
  public function countValues()
201
  {
202
    return new static(\array_count_values($this->array));
203
  }
204
205
  /**
206
   * Exchange the array for another one.
207 1
   *
208
   * @param array|Arrayy $data
209 1
   *
210
   * @return array
211
   */
212
  public function exchangeArray($data)
213
  {
214
    $this->array = $this->fallbackForArray($data);
215
216
    return $this->array;
217 20
  }
218
219 20
  /**
220
   * Creates a copy of the ArrayyObject.
221 20
   *
222
   * @return array
223
   */
224
  public function getArrayCopy()
225
  {
226
    return $this->array;
227
  }
228
229 20
  /**
230
   * Returns a new ArrayyIterator, thus implementing the IteratorAggregate interface.
231 20
   *
232
   * @return ArrayyIterator <p>An iterator for the values in the array.</p>
233
   */
234
  public function getIterator()
235
  {
236
    $iterator = $this->getIteratorClass();
237
238
    return new $iterator($this->array);
239
  }
240
241
  /**
242
   * Gets the iterator classname for the ArrayObject.
243
   *
244
   * @return string
245 4
   */
246
  public function getIteratorClass()
247 4
  {
248
    return $this->iteratorClass;
249 4
  }
250
251
  /**
252
   * Sort the entries by key
253
   *
254
   * @param int $sort_flags [optional] <p>
255
   *                        You may modify the behavior of the sort using the optional
256
   *                        parameter sort_flags, for details
257
   *                        see sort.
258
   *                        </p>
259
   *
260
   * @return static <p>(Mutable) Return this Arrayy object.</p>
261
   */
262
  public function ksort($sort_flags = null)
263
  {
264
    ksort($this->array, $sort_flags);
265
266
    return $this;
267
  }
268
269 1
  /**
270
   * Sort an array using a case insensitive "natural order" algorithm
271 1
   *
272
   * @return static <p>(Mutable) Return this Arrayy object.</p>
273 1
   */
274
  public function natcasesort()
275
  {
276
    natcasesort($this->array);
277
278
    return $this;
279
  }
280
281
  /**
282
   * Sort entries using a "natural order" algorithm
283 40
   *
284
   * @return static <p>(Mutable) Return this Arrayy object.</p>
285 40
   */
286 4
  public function natsort()
287
  {
288
    natsort($this->array);
289
290 36
    return $this;
291 1
  }
292 1
293
  /**
294 36
   * Whether or not an offset exists.
295
   *
296
   * @param int|float|string $offset
297
   *
298 36
   * @return bool
299
   */
300
  public function offsetExists($offset)
301 12
  {
302 12
    if ($this->isEmpty()) {
303 12
      return false;
304 36
    }
305 34
306
    // php cast "bool"-index into "int"-index
307
    if ((bool)$offset === $offset) {
308 3
      $offset = (int)$offset;
309
    }
310 3
311
    $tmpReturn = \array_key_exists($offset, $this->array);
312 3
313 3
    if (
314 3
        $tmpReturn === true
315 3
        ||
316
        (
317 3
            $tmpReturn === false
318 3
            &&
319
            strpos((string)$offset, $this->pathSeparator) === false
320 3
        )
321 3
    ) {
322 3
      return $tmpReturn;
323 3
    }
324
325 3
    $offsetExists = false;
326
327
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
328
329
      $offsetExists = false;
330
      $explodedPath = explode($this->pathSeparator, (string)$offset);
331
      $lastOffset = \array_pop($explodedPath);
332
      $containerPath = implode($this->pathSeparator, $explodedPath);
333
334
      $this->callAtPath(
335 26
          $containerPath,
336
          function ($container) use ($lastOffset, &$offsetExists) {
337 26
            $offsetExists = \array_key_exists($lastOffset, $container);
338
          }
339
      );
340
    }
341
342
    return $offsetExists;
343
  }
344
345
  /**
346 17
   * Returns the value at specified offset.
347
   *
348 17
   * @param mixed $offset
349 4
   *
350 4
   * @return mixed <p>Will return null if the offset did not exists.</p>
351 13
   */
352
  public function offsetGet($offset)
353 17
  {
354
    return $this->offsetExists($offset) ? $this->get($offset) : null;
355
  }
356
357
  /**
358
   * Assigns a value to the specified offset.
359
   *
360 7
   * @param mixed $offset
361
   * @param mixed $value
362 7
   */
363 1
  public function offsetSet($offset, $value)
364
  {
365
    if ($offset === null) {
366 6
      $this->array[] = $value;
367 4
    } else {
368
      $this->internalSet($offset, $value);
369 4
    }
370
  }
371
372 3
  /**
373
   * Unset an offset.
374 2
   *
375 2
   * @param mixed $offset
376
   */
377 2
  public function offsetUnset($offset)
378 2
  {
379
    if ($this->isEmpty()) {
380 2
      return;
381 2
    }
382 2
383
    if (\array_key_exists($offset, $this->array)) {
384 2
      unset($this->array[$offset]);
385 3
386
      return;
387
    }
388
389
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
390
391
      $path = explode($this->pathSeparator, (string)$offset);
392 1
      $pathToUnset = \array_pop($path);
393
394 1
      $this->callAtPath(
395
          implode($this->pathSeparator, $path),
396
          function (&$offset) use ($pathToUnset) {
397
            unset($offset[$pathToUnset]);
398
          }
399
      );
400
401
    }
402
  }
403
404
  /**
405
   * Serialize the current "Arrayy"-object.
406 766
   *
407
   * @return string
408 766
   */
409 766
  public function serialize()
410
  {
411 766
    return parent::serialize();
412
  }
413
414
  /**
415
   * Sets the iterator classname for the current "Arrayy"-object.
416
   *
417
   * @param  string $class
418
   *
419
   * @return void
420
   *
421
   * @throws \InvalidArgumentException
422
   */
423
  public function setIteratorClass($class)
424
  {
425
    if (class_exists($class)) {
426
      $this->iteratorClass = $class;
427
428
      return;
429
    }
430
431
    if (strpos($class, '\\') === 0) {
432
      $class = '\\' . $class;
433
      if (class_exists($class)) {
434
        $this->iteratorClass = $class;
435
436
        return;
437
      }
438
    }
439
440
    throw new \InvalidArgumentException('The iterator class does not exist: ' . $class);
441
  }
442
443
  /**
444
   * Sort the entries with a user-defined comparison function and maintain key association.
445
   *
446
   * @param callable $function
447
   *
448
   * @return static <p>(Mutable) Return this Arrayy object.</p>
449
   *
450
   * @throws \InvalidArgumentException
451
   */
452 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...
453
  {
454
    if (!is_callable($function)) {
455
      throw new \InvalidArgumentException(
456
          'Passed function must be callable'
457 5
      );
458
    }
459 5
460
    uasort($this->array, $function);
461
462
    return $this;
463
  }
464
465
  /**
466
   * Sort the entries by keys using a user-defined comparison function.
467
   *
468
   * @param callable $function
469 1
   *
470
   * @return static <p>(Mutable) Return this Arrayy object.</p>
471 1
   *
472
   * @throws \InvalidArgumentException
473 1
   */
474
  public function uksort($function)
475
  {
476
    return $this->customSortKeys($function);
477
  }
478
479
  /**
480
   * Unserialize an string and return this object.
481 4
   *
482
   * @param string $string
483 4
   *
484
   * @return static <p>(Mutable)</p>
485 4
   */
486
  public function unserialize($string)
487
  {
488
    parent::unserialize($string);
489
490
    return $this;
491
  }
492
493
  /**
494
   * Sort an array in reverse order and maintain index association.
495 2
   *
496
   * @return static <p>(Mutable) Return this Arrayy object.</p>
497 2
   */
498
  public function arsort()
499 2
  {
500 2
    arsort($this->array);
501 2
502
    return $this;
503 2
  }
504
505
  /**
506
   * Iterate over the current array and execute a callback for each loop.
507
   *
508
   * @param \Closure $closure
509
   *
510
   * @return static <p>(Immutable)</p>
511
   */
512 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...
513 10
  {
514
    $array = $this->array;
515 10
516
    foreach ($array as $key => $value) {
517 10
      $closure($value, $key);
518 2
    }
519
520
    return static::create($array);
521 8
  }
522 3
523 3
  /**
524
   * Returns the average value of the current array.
525 8
   *
526
   * @param int $decimals <p>The number of decimal-numbers to return.</p>
527
   *
528
   * @return int|double <p>The average value.</p>
529
   */
530
  public function average($decimals = 0)
531
  {
532
    $count = $this->count();
533 4
534
    if (!$count) {
535 4
      return 0;
536 4
    }
537 4
538
    if (!is_int($decimals)) {
539 4
      $decimals = 0;
540 4
    }
541
542 4
    return round(\array_sum($this->array) / $count, $decimals);
543
  }
544
545
  /**
546 4
   * @param mixed      $path
547 1
   * @param callable   $callable
548 1
   * @param null|array $currentOffset
549 1
   */
550 1
  protected function callAtPath($path, $callable, &$currentOffset = null)
551 1
  {
552 1
    if ($currentOffset === null) {
553 4
      $currentOffset = &$this->array;
554
    }
555 4
556
    $explodedPath = explode($this->pathSeparator, $path);
557
    $nextPath = \array_shift($explodedPath);
558
559
    if (!isset($currentOffset[$nextPath])) {
560
      return;
561
    }
562
563
    if (!empty($explodedPath)) {
564
      $this->callAtPath(
565 1
          implode($this->pathSeparator, $explodedPath),
566
          $callable,
567 1
          $currentOffset[$nextPath]
568
      );
569
    } else {
570
      $callable($currentOffset[$nextPath]);
571
    }
572
  }
573
574
  /**
575
   * Changes all keys in an array.
576
   *
577
   * @param int $case [optional] <p> Either <strong>CASE_UPPER</strong><br />
578
   *                  or <strong>CASE_LOWER</strong> (default)</p>
579 1
   *
580
   * @return static <p>(Immutable)</p>
581 1
   */
582
  public function changeKeyCase($case = CASE_LOWER)
583 1
  {
584
    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...
585
  }
586
587
  /**
588
   * Change the path separator of the array wrapper.
589
   *
590
   * By default, the separator is: "."
591
   *
592
   * @param string $separator <p>Separator to set.</p>
593
   *
594 4
   * @return static <p>Mutable</p>
595
   */
596 4
  public function changeSeparator($separator)
597
  {
598 4
    $this->pathSeparator = $separator;
599
600
    return $this;
601
  }
602
603
  /**
604
   * Create a chunked version of the current array.
605
   *
606 8
   * @param int  $size         <p>Size of each chunk.</p>
607
   * @param bool $preserveKeys <p>Whether array keys are preserved or no.</p>
608 8
   *
609
   * @return static <p>(Immutable) A new array of chunks from the original array.</p>
610 7
   */
611
  public function chunk($size, $preserveKeys = false)
612 8
  {
613
    $result = \array_chunk($this->array, $size, $preserveKeys);
614
615
    return static::create($result);
616
  }
617
618
  /**
619
   * Clean all falsy values from the current array.
620 4
   *
621
   * @return static <p>(Immutable)</p>
622 4
   */
623
  public function clean()
624 4
  {
625
    return $this->filter(
626
        function ($value) {
627
          return (bool)$value;
628
        }
629
    );
630
  }
631
632
  /**
633
   * WARNING!!! -> Clear the current array.
634 13
   *
635
   * @return static <p>(Mutable) Return this Arrayy object, with an empty array.</p>
636 13
   */
637
  public function clear()
638
  {
639
    $this->array = array();
640
641
    return $this;
642
  }
643
644
  /**
645
   * Check if an item is in the current array.
646 13
   *
647
   * @param string|int|float $value
648 13
   *
649 13
   * @return bool
650 13
   */
651
  public function contains($value)
652 13
  {
653 13
    return in_array($value, $this->array, true);
654 13
  }
655 13
656 13
  /**
657
   * Check if an (case-insensitive) string is in the current array.
658 13
   *
659
   * @param string $value
660
   *
661
   * @return bool
662
   */
663
  public function containsCaseInsensitive($value)
664
  {
665
    return in_array(
666
        UTF8::strtolower($value),
667
        \array_map(
668 4
            array(
669
                new UTF8(),
670 4
                'strtolower',
671
            ),
672
            $this->array
673
        ),
674
        true
675
    );
676
  }
677
678
  /**
679
   * Check if the given key/index exists in the array.
680 1
   *
681
   * @param string|int|float $key <p>key/index to search for</p>
682 1
   *
683
   * @return bool <p>Returns true if the given key/index exists in the array, false otherwise.</p>
684
   */
685
  public function containsKey($key)
686
  {
687
    return $this->offsetExists($key);
688
  }
689
690
  /**
691
   * Check if all given needles are present in the array as key/index.
692
   *
693
   * @param array $needles
694 9
   *
695
   * @return bool <p>Returns true if the given keys/indexes exists in the array, false otherwise.</p>
696 9
   */
697
  public function containsKeys(array $needles)
698
  {
699
    return count(\array_intersect($needles, $this->keys()->getArray())) === count($needles);
700
  }
701
702
  /**
703
   * alias: for "Arrayy->contains()"
704
   *
705
   * @see Arrayy::contains()
706 1
   *
707
   * @param string|int|float $value
708 1
   *
709
   * @return bool
710
   */
711
  public function containsValue($value)
712
  {
713
    return $this->contains($value);
714
  }
715
716
  /**
717
   * Check if all given needles are present in the array.
718 480
   *
719
   * @param array $needles
720 480
   *
721
   * @return bool <p>Returns true if the given values exists in the array, false otherwise.</p>
722
   */
723
  public function containsValues(array $needles)
724
  {
725
    return count(\array_intersect($needles, $this->array)) === count($needles);
726
  }
727
728
  /**
729
   * Creates an Arrayy object.
730 1
   *
731
   * @param array $array
732 1
   *
733
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
734 1
   */
735
  public static function create($array = array())
736 1
  {
737
    return new static($array);
738
  }
739
740
  /**
741
   * WARNING: Creates an Arrayy object by reference.
742
   *
743
   * @param array $array
744
   *
745
   * @return static <p>(Mutable) Return this Arrayy object.</p>
746 5
   */
747
  public function createByReference(&$array = array())
748 5
  {
749
    $array = $this->fallbackForArray($array);
750 5
751
    $this->array = &$array;
752
753
    return $this;
754
  }
755
756
  /**
757
   * Create an new Arrayy object via JSON.
758
   *
759
   * @param string $json
760 4
   *
761
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
762 4
   */
763 4
  public static function createFromJson($json)
764
  {
765 3
    $array = UTF8::json_decode($json, true);
766 4
767
    return static::create($array);
768 4
  }
769
770
  /**
771
   * Create an new instance filled with values from an object that have implemented ArrayAccess.
772
   *
773
   * @param \ArrayAccess $object <p>Object that implements ArrayAccess</p>
774
   *
775
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
776
   */
777
  public static function createFromObject(\ArrayAccess $object)
778
  {
779
    $array = new static();
780
    foreach ($object as $key => $value) {
781 8
      /** @noinspection OffsetOperationsInspection */
782
      $array[$key] = $value;
783 8
    }
784 1
785
    return $array;
786 1
  }
787 1
788 1
  /**
789
   * Create an new Arrayy object via string.
790 1
   *
791 7
   * @param string      $str       <p>The input string.</p>
792
   * @param string|null $delimiter <p>The boundary string.</p>
793
   * @param string|null $regEx     <p>Use the $delimiter or the $regEx, so if $pattern is null, $delimiter will be
794
   *                               used.</p>
795 8
   *
796
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
797
   */
798
  public static function createFromString($str, $delimiter, $regEx = null)
799 8
  {
800 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...
801 8
      preg_match_all($regEx, $str, $array);
802 8
803 8
      if (!empty($array)) {
804
        $array = $array[0];
805 8
      }
806
807
    } else {
808
      $array = explode($delimiter, $str);
809
    }
810
811
    // trim all string in the array
812
    \array_walk(
813
        $array,
814
        function (&$val) {
815
          /** @noinspection ReferenceMismatchInspection */
816
          if (is_string($val)) {
817 1
            $val = trim($val);
818
          }
819 1
        }
820
    );
821
822
    return static::create($array);
823
  }
824
825
  /**
826
   * Create an new instance containing a range of elements.
827
   *
828
   * @param mixed $low  <p>First value of the sequence.</p>
829
   * @param mixed $high <p>The sequence is ended upon reaching the end value.</p>
830
   * @param int   $step <p>Used as the increment between elements in the sequence.</p>
831
   *
832
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
833 5
   */
834
  public static function createWithRange($low, $high, $step = 1)
835 5
  {
836
    return static::create(range($low, $high, $step));
837
  }
838
839
  /**
840
   * Custom sort by index via "uksort".
841 5
   *
842
   * @link http://php.net/manual/en/function.uksort.php
843 5
   *
844
   * @param callable $function
845
   *
846
   * @return static <p>(Mutable) Return this Arrayy object.</p>
847
   *
848
   * @throws \InvalidArgumentException
849
   */
850 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...
851
  {
852
    if (!is_callable($function)) {
853
      throw new \InvalidArgumentException(
854
          'Passed function must be callable'
855
      );
856
    }
857 5
858
    uksort($this->array, $function);
859 5
860
    return $this;
861
  }
862
863
  /**
864
   * Custom sort by value via "usort".
865 5
   *
866
   * @link http://php.net/manual/en/function.usort.php
867 5
   *
868
   * @param callable $function
869
   *
870
   * @return static <p>(Mutable) Return this Arrayy object.</p>
871
   *
872
   * @throws \InvalidArgumentException
873
   */
874 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...
875
  {
876
    if (!is_callable($function)) {
877 12
      throw new \InvalidArgumentException(
878
          'Passed function must be callable'
879 12
      );
880
    }
881 12
882
    usort($this->array, $function);
883
884
    return $this;
885
  }
886
887
  /**
888
   * Return values that are only in the current array.
889
   *
890
   * @param array $array
891
   *
892 1
   * @return static <p>(Immutable)</p>
893
   */
894 1
  public function diff(array $array = array())
895
  {
896
    $result = \array_diff($this->array, $array);
897
898 1
    return static::create($result);
899 1
  }
900 1
901 1
  /**
902 1
   * Return values that are only in the current multi-dimensional array.
903 1
   *
904
   * @param array      $array
905
   * @param null|array $helperVariableForRecursion <p>(only for internal usage)</p>
906 1
   *
907 1
   * @return static <p>(Immutable)</p>
908 1
   */
909 1
  public function diffRecursive(array $array = array(), $helperVariableForRecursion = null)
910 1
  {
911 1
    $result = array();
912 1
913 1
    if (
914 1
        $helperVariableForRecursion !== null
915 1
        &&
916 1
        is_array($helperVariableForRecursion)
917
    ) {
918 1
      $arrayForTheLoop = $helperVariableForRecursion;
919 1
    } else {
920
      $arrayForTheLoop = $this->array;
921 1
    }
922
923 1
    foreach ($arrayForTheLoop as $key => $value) {
924
      if (\array_key_exists($key, $array)) {
925
        if (is_array($value)) {
926
          $recursiveDiff = $this->diffRecursive($array[$key], $value);
927
          if (!empty($recursiveDiff)) {
928
            $result[$key] = $recursiveDiff;
929
          }
930
        } else {
931
          if ($value != $array[$key]) {
932
            $result[$key] = $value;
933 8
          }
934
        }
935 8
      } else {
936
        $result[$key] = $value;
937 8
      }
938
    }
939
940
    return static::create($result);
941
  }
942
943
  /**
944
   * Return values that are only in the new $array.
945 1
   *
946
   * @param array $array
947 1
   *
948
   * @return static <p>(Immutable)</p>
949 1
   */
950 1
  public function diffReverse(array $array = array())
951
  {
952 1
    $result = \array_diff($array, $this->array);
953
954
    return static::create($result);
955
  }
956
957
  /**
958
   * Divide an array into two arrays. One with keys and the other with values.
959
   *
960
   * @return static <p>(Immutable)</p>
961
   */
962 4
  public function divide()
963
  {
964 4
    return static::create(
965
        array(
966 4
            $this->keys(),
967 4
            $this->values(),
968 4
        )
969
    );
970 4
  }
971
972
  /**
973
   * Iterate over the current array and modify the array's value.
974
   *
975
   * @param \Closure $closure
976
   *
977
   * @return static <p>(Immutable)</p>
978
   */
979 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...
980 4
  {
981
    $array = $this->array;
982 4
983 4
    foreach ($array as $key => $value) {
984 3
      $array[$key] = $closure($value, $key);
985 1
    }
986 1
987
    return static::create($array);
988 4
  }
989
990 4
  /**
991
   * Check if a value is in the current array using a closure.
992
   *
993
   * @param \Closure $closure
994
   *
995
   * @return bool <p>Returns true if the given value is found, false otherwise.</p>
996
   */
997
  public function exists(\Closure $closure)
998
  {
999
    $isExists = false;
1000
    foreach ($this->array as $key => $value) {
1001
      if ($closure($value, $key)) {
1002
        $isExists = true;
1003
        break;
1004
      }
1005
    }
1006
1007
    return $isExists;
1008
  }
1009
1010 768
  /**
1011
   * create a fallback for array
1012 768
   *
1013 765
   * 1. use the current array, if it's a array
1014
   * 2. call "getArray()" on object, if there is a "Arrayy"-object
1015
   * 3. fallback to empty array, if there is nothing
1016 11
   * 4. call "createFromObject()" on object, if there is a "\ArrayAccess"-object
1017 1
   * 5. call "__toArray()" on object, if the method exists
1018
   * 6. cast a string or object with "__toString()" into an array
1019
   * 7. throw a "InvalidArgumentException"-Exception
1020 10
   *
1021 6
   * @param $array
1022
   *
1023
   * @return array
1024 9
   *
1025
   * @throws \InvalidArgumentException
1026 9
   */
1027
  protected function fallbackForArray(&$array)
1028
  {
1029
    if (is_array($array)) {
1030
      return $array;
1031 9
    }
1032
1033
    if ($array instanceof self) {
1034
      return $array->getArray();
1035 9
    }
1036
1037
    if (!$array) {
1038
      return array();
1039
    }
1040
1041 9
    $isObject = is_object($array);
1042
1043 2
    if ($isObject && $array instanceof \ArrayAccess) {
1044 9
      /** @noinspection ReferenceMismatchInspection */
1045 7
      return static::createFromObject($array)->getArray();
1046
    }
1047
1048 2
    if ($isObject && $array instanceof \ArrayObject) {
1049
      return $array->getArrayCopy();
1050 2
    }
1051
1052
    if ($isObject && method_exists($array, '__toArray')) {
1053
      return (array)$array->__toArray();
1054
    }
1055
1056
    /** @noinspection ReferenceMismatchInspection */
1057
    if (
1058
        is_string($array)
1059
        ||
1060 9
        ($isObject && method_exists($array, '__toString'))
1061
    ) {
1062 9
      return array((string)$array);
1063 1
    }
1064
1065
    throw new \InvalidArgumentException(
1066 9
        'Passed value should be a array'
1067
    );
1068 9
  }
1069
1070
  /**
1071
   * Find all items in an array that pass the truth test.
1072
   *
1073
   * @param \Closure|null $closure [optional] <p>
1074
   *                               The callback function to use
1075
   *                               </p>
1076
   *                               <p>
1077
   *                               If no callback is supplied, all entries of
1078
   *                               input equal to false (see
1079
   *                               converting to
1080
   *                               boolean) will be removed.
1081
   *                               </p>
1082
   *
1083
   *  * @param int $flag [optional] <p>
1084
   *                               Flag determining what arguments are sent to <i>callback</i>:
1085
   *                               </p><ul>
1086
   *                               <li>
1087
   *                               <b>ARRAY_FILTER_USE_KEY</b> [1] - pass key as the only argument
1088
   *                               to <i>callback</i> instead of the value</span>
1089
   *                               </li>
1090
   *                               <li>
1091
   *                               <b>ARRAY_FILTER_USE_BOTH</b> [2] - pass both value and key as
1092
   *                               arguments to <i>callback</i> instead of the value</span>
1093 1
   *                               </li>
1094
   *                               </ul>
1095 1
   *
1096 1
   * @return static <p>(Immutable)</p>
1097 1
   */
1098
  public function filter($closure = null, $flag = 0)
1099
  {
1100
    if (!$closure) {
1101 1
      return $this->clean();
1102 1
    }
1103
1104
    if ($flag === 0) {
1105 1
1106
      // working for all php-versions
1107
1108 1
      $array = \array_filter($this->array, $closure);
1109
1110
    } elseif ($flag !== 0 && Bootup::is_php('5.6')) {
1111 1
1112
      // working only with php >= 5.6
1113 1
1114 1
      $array = \array_filter($this->array, $closure, $flag);
1115
1116
    } else {
1117 1
1118
      // fallback for old php-versions
1119
1120 1
      $array = $this->array;
1121
1122
      if ($flag === 2 /* ARRAY_FILTER_USE_KEY */) {
1123 1
        foreach ($array as $key => $value) {
1124
          if (!call_user_func($closure, $key)) {
1125 1
            unset ($array[$key]);
1126 1
          }
1127
        }
1128
      } else if ($flag === 1 /* ARRAY_FILTER_USE_BOTH */) {
1129 1
        foreach ($array as $key => $value) {
1130
          if (!call_user_func($closure, $key, $value)) {
1131
            unset($array[$key]);
1132 1
          }
1133
        }
1134
      }
1135 1
    }
1136 1
1137
    return static::create($array);
1138 1
  }
1139 1
1140 1
  /**
1141
   * Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property
1142 1
   * within that.
1143 1
   *
1144 1
   * @param string $property
1145 1
   * @param string $value
1146
   * @param string $comparisonOp
1147 1
   *                            <p>
1148 1
   *                            'eq' (equals),<br />
1149 1
   *                            'gt' (greater),<br />
1150
   *                            'gte' || 'ge' (greater or equals),<br />
1151 1
   *                            'lt' (less),<br />
1152
   *                            'lte' || 'le' (less or equals),<br />
1153 1
   *                            'ne' (not equals),<br />
1154 1
   *                            'contains',<br />
1155
   *                            'notContains',<br />
1156 1
   *                            'newer' (via strtotime),<br />
1157
   *                            'older' (via strtotime),<br />
1158
   *                            </p>
1159
   *
1160
   * @return static <p>(Immutable)</p>
1161
   */
1162
  public function filterBy($property, $value, $comparisonOp = null)
1163
  {
1164
    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...
1165
      $comparisonOp = is_array($value) ? 'contains' : 'eq';
1166
    }
1167 8
1168
    $ops = array(
1169 8
        'eq'          => function ($item, $prop, $value) {
1170 6
          return $item[$prop] === $value;
1171 5
        },
1172
        'gt'          => function ($item, $prop, $value) {
1173 5
          return $item[$prop] > $value;
1174
        },
1175 3
        'ge'          => function ($item, $prop, $value) {
1176
          return $item[$prop] >= $value;
1177
        },
1178
        'gte'         => function ($item, $prop, $value) {
1179
          return $item[$prop] >= $value;
1180
        },
1181
        'lt'          => function ($item, $prop, $value) {
1182
          return $item[$prop] < $value;
1183
        },
1184
        'le'          => function ($item, $prop, $value) {
1185
          return $item[$prop] <= $value;
1186
        },
1187
        'lte'         => function ($item, $prop, $value) {
1188
          return $item[$prop] <= $value;
1189
        },
1190
        'ne'          => function ($item, $prop, $value) {
1191
          return $item[$prop] !== $value;
1192
        },
1193
        'contains'    => function ($item, $prop, $value) {
1194
          return in_array($item[$prop], (array)$value, true);
1195
        },
1196
        'notContains' => function ($item, $prop, $value) {
1197 13
          return !in_array($item[$prop], (array)$value, true);
1198
        },
1199 13
        'newer'       => function ($item, $prop, $value) {
1200 13
          return strtotime($item[$prop]) > strtotime($value);
1201
        },
1202 13
        'older'       => function ($item, $prop, $value) {
1203 3
          return strtotime($item[$prop]) < strtotime($value);
1204
        },
1205
    );
1206 10
1207
    $result = \array_values(
1208
        \array_filter(
1209
            (array)$this->array,
1210
            function ($item) use (
1211
                $property,
1212
                $value,
1213
                $ops,
1214
                $comparisonOp
1215
            ) {
1216 28
              $item = (array)$item;
1217
              $itemArrayy = new Arrayy($item);
1218 28
              $item[$property] = $itemArrayy->get($property, array());
1219 7
1220 7
              return $ops[$comparisonOp]($item, $property, $value);
1221 7
            }
1222 21
        )
1223 21
    );
1224 21
1225
    return static::create($result);
1226
  }
1227 28
1228
  /**
1229
   * Find the first item in an array that passes the truth test,
1230
   *  otherwise return false
1231
   *
1232
   * @param \Closure $closure
1233
   *
1234
   * @return mixed|false <p>Return false if we did not find the value.</p>
1235
   */
1236
  public function find(\Closure $closure)
1237 26
  {
1238
    foreach ($this->array as $key => $value) {
1239 26
      if ($closure($value, $key)) {
1240 11
        return $value;
1241 11
      }
1242 15
    }
1243 15
1244
    return false;
1245
  }
1246 26
1247
  /**
1248
   * find by ...
1249
   *
1250
   * @param string $property
1251
   * @param string $value
1252
   * @param string $comparisonOp
1253
   *
1254 1
   * @return static <p>(Immutable)</p>
1255
   */
1256 1
  public function findBy($property, $value, $comparisonOp = 'eq')
1257
  {
1258 1
    return $this->filterBy($property, $value, $comparisonOp);
1259
  }
1260
1261
  /**
1262
   * Get the first value from the current array.
1263
   *
1264
   * @return mixed <p>Return null if there wasn't a element.</p>
1265
   */
1266
  public function first()
1267
  {
1268
    $tmpArray = $this->array;
1269
    $result = \array_shift($tmpArray);
1270
1271 61
    if ($result === null) {
1272
      return null;
1273
    }
1274
1275 61
    return $result;
1276 3
  }
1277 61
1278 3
  /**
1279 3
   * Get the first value(s) from the current array.
1280 59
   *
1281
   * @param int|null $number <p>How many values you will take?</p>
1282
   *
1283 61
   * @return static <p>(Immutable)</p>
1284 1
   */
1285
  public function firstsImmutable($number = null)
1286
  {
1287
    if ($number === null) {
1288 61
      $arrayTmp = $this->array;
1289 2
      $array = (array)\array_shift($arrayTmp);
1290 2
    } else {
1291
      $number = (int)$number;
1292 61
      $arrayTmp = $this->array;
1293 51
      $array = \array_splice($arrayTmp, 0, $number, true);
1294 6
    }
1295
1296
    return static::create($array);
1297 47
  }
1298
1299
  /**
1300
   * Get the first value(s) from the current array.
1301 20
   *
1302 20
   * @param int|null $number <p>How many values you will take?</p>
1303 19
   *
1304
   * @return static <p>(Mutable)</p>
1305
   */
1306 5
  public function firstsMutable($number = null)
1307 5
  {
1308
    if ($number === null) {
1309 5
      $this->array = (array)\array_shift($this->array);
1310
    } else {
1311
      $number = (int)$number;
1312
      $this->array = \array_splice($this->array, 0, $number, true);
1313 5
    }
1314
1315
    return $this;
1316
  }
1317
1318
  /**
1319
   * Exchanges all keys with their associated values in an array.
1320
   *
1321 490
   * @return static <p>(Immutable)</p>
1322
   */
1323 490
  public function flip()
1324
  {
1325 490
    $result = \array_flip($this->array);
1326
1327
    return static::create($result);
1328
  }
1329
1330
  /**
1331
   * Get a value from an array (optional using dot-notation).
1332
   *
1333
   * @param string $key      <p>The key to look for.</p>
1334
   * @param mixed  $fallback <p>Value to fallback to.</p>
1335
   * @param array  $array    <p>The array to get from, if it's set to "null" we use the current array from the
1336
   *                         class.</p>
1337
   *
1338
   * @return mixed
1339
   */
1340 1
  public function get($key, $fallback = null, $array = null)
1341
  {
1342 1
    if (
1343
        $array !== null
1344 1
        &&
1345
        is_array($array)
1346
    ) {
1347
      $usedArray = $array;
1348
    } else {
1349
      $usedArray = $this->array;
1350
    }
1351
1352
    if ($key === null) {
1353
      return static::create($usedArray);
1354 38
    }
1355
1356 38
    // php cast "bool"-index into "int"-index
1357 10
    if ((bool)$key === $key) {
1358
      $key = (int)$key;
1359 10
    }
1360 2
1361 2
    if (\array_key_exists($key, $usedArray) === true) {
1362 8
      if (is_array($usedArray[$key])) {
1363
        return static::create($usedArray[$key]);
1364 10
      }
1365
1366
      return $usedArray[$key];
1367
    }
1368 38
1369
    // Crawl through array, get key according to object or not
1370 38
    foreach (explode($this->pathSeparator, (string)$key) as $segment) {
1371
      if (!isset($usedArray[$segment])) {
1372
        return $fallback instanceof \Closure ? $fallback() : $fallback;
1373
      }
1374 38
1375
      $usedArray = $usedArray[$segment];
1376
    }
1377
1378
    if (is_array($usedArray)) {
1379
      return static::create($usedArray);
1380
    }
1381
1382
    return $usedArray;
1383
  }
1384 1
1385
  /**
1386 1
   * Get the current array from the "Arrayy"-object.
1387
   *
1388
   * @return array
1389
   */
1390
  public function getArray()
1391
  {
1392
    \array_map(array('self', 'internalGetArray'), $this->array);
1393
1394
    return $this->array;
1395
  }
1396 3
1397
  /**
1398 3
   * Returns the values from a single column of the input array, identified by
1399
   * the $columnKey, can be used to extract data-columns from multi-arrays.
1400
   *
1401
   * Info: Optionally, you may provide an $indexKey to index the values in the returned
1402
   * array by the values from the $indexKey column in the input array.
1403
   *
1404
   * @param mixed $columnKey
1405
   * @param mixed $indexKey
1406
   *
1407
   * @return static <p>(Immutable)</p>
1408 3
   */
1409
  public function getColumn($columnKey = null, $indexKey = null)
1410 3
  {
1411
    $result = \array_column($this->array, $columnKey, $indexKey);
1412
1413
    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 1411 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...
1414
  }
1415
1416
  /**
1417
   * Get correct PHP constant for direction.
1418
   *
1419
   * @param int|string $direction
1420
   *
1421
   * @return int
1422 9
   */
1423
  protected function getDirection($direction)
1424 9
  {
1425
    if (is_string($direction)) {
1426
      $direction = strtolower($direction);
1427
1428
      if ($direction === 'desc') {
1429
        $direction = SORT_DESC;
1430
      } else {
1431
        $direction = SORT_ASC;
1432
      }
1433
    }
1434 3
1435
    if (
1436 3
        $direction !== SORT_DESC
1437
        &&
1438
        $direction !== SORT_ASC
1439
    ) {
1440
      $direction = SORT_ASC;
1441
    }
1442
1443
    return $direction;
1444
  }
1445
1446
  /**
1447
   * alias: for "Arrayy->keys()"
1448 6
   *
1449
   * @see Arrayy::keys()
1450 6
   *
1451
   * @return static <p>(Immutable)</p>
1452
   */
1453
  public function getKeys()
1454
  {
1455
    return $this->keys();
1456
  }
1457
1458
  /**
1459
   * alias: for "Arrayy->randomImmutable()"
1460
   *
1461 3
   * @see Arrayy::randomImmutable()
1462
   *
1463 3
   * @return static <p>(Immutable)</p>
1464 3
   */
1465
  public function getRandom()
1466
  {
1467 3
    return $this->randomImmutable();
1468
  }
1469 3
1470 3
  /**
1471
   * alias: for "Arrayy->randomKey()"
1472 3
   *
1473
   * @see Arrayy::randomKey()
1474
   *
1475
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
1476 3
   */
1477 3
  public function getRandomKey()
1478 3
  {
1479
    return $this->randomKey();
1480
  }
1481 3
1482 2
  /**
1483 1
   * alias: for "Arrayy->randomKeys()"
1484 1
   *
1485 1
   * @see Arrayy::randomKeys()
1486 1
   *
1487 1
   * @param int $number
1488
   *
1489 2
   * @return static <p>(Immutable)</p>
1490
   */
1491 3
  public function getRandomKeys($number)
1492
  {
1493 3
    return $this->randomKeys($number);
1494
  }
1495
1496
  /**
1497
   * alias: for "Arrayy->randomValue()"
1498
   *
1499
   * @see Arrayy::randomValue()
1500
   *
1501
   * @return mixed <p>get a random value or null if there wasn't a value.</p>
1502
   */
1503 22
  public function getRandomValue()
1504
  {
1505
    return $this->randomValue();
1506 22
  }
1507
1508 22
  /**
1509
   * alias: for "Arrayy->randomValues()"
1510
   *
1511
   * @see Arrayy::randomValues()
1512
   *
1513
   * @param int $number
1514
   *
1515
   * @return static <p>(Immutable)</p>
1516
   */
1517
  public function getRandomValues($number)
1518 27
  {
1519
    return $this->randomValues($number);
1520 27
  }
1521
1522
  /**
1523
   * Group values from a array according to the results of a closure.
1524
   *
1525
   * @param string $grouper <p>A callable function name.</p>
1526
   * @param bool   $saveKeys
1527
   *
1528
   * @return static <p>(Immutable)</p>
1529
   */
1530
  public function group($grouper, $saveKeys = false)
1531
  {
1532
    $array = (array)$this->array;
1533
    $result = array();
1534 3
1535
    // Iterate over values, group by property/results from closure
1536 3
    foreach ($array as $key => $value) {
1537
1538 3
      $groupKey = is_callable($grouper) ? $grouper($value, $key) : $this->get($grouper, null, $value);
1539 3
      $newValue = $this->get($groupKey, null, $result);
1540 2
1541 2
      if ($groupKey instanceof self) {
1542 3
        $groupKey = $groupKey->getArray();
1543
      }
1544 3
1545
      if ($newValue instanceof self) {
1546
        $newValue = $newValue->getArray();
1547
      }
1548
1549
      // Add to results
1550
      if ($groupKey !== null) {
1551
        if ($saveKeys) {
1552
          $result[$groupKey] = $newValue;
1553
          $result[$groupKey][$key] = $value;
1554
        } else {
1555
          $result[$groupKey] = $newValue;
1556 4
          $result[$groupKey][] = $value;
1557
        }
1558 4
      }
1559
1560
    }
1561
1562
    return static::create($result);
1563
  }
1564
1565
  /**
1566
   * Check if an array has a given key.
1567
   *
1568 12
   * @param mixed $key
1569
   *
1570 12
   * @return bool
1571
   */
1572 12
  public function has($key)
1573
  {
1574
    // Generate unique string to use as marker.
1575
    $unFound = (string)uniqid('arrayy', true);
1576
1577
    return $this->get($key, $unFound) !== $unFound;
1578 405
  }
1579
1580 405
  /**
1581
   * Implodes an array.
1582 405
   *
1583
   * @param string $glue
1584
   *
1585 405
   * @return string
1586
   */
1587
  public function implode($glue = '')
1588
  {
1589
    return implode($glue, $this->array);
1590
  }
1591
1592
  /**
1593
   * Given a list and an iterate-function that returns
1594 18
   * a key for each element in the list (or a property name),
1595
   * returns an object with an index of each item.
1596 18
   *
1597
   * Just like groupBy, but for when you know your keys are unique.
1598
   *
1599 18
   * @param mixed $key
1600
   *
1601
   * @return static <p>(Immutable)</p>
1602
   */
1603
  public function indexBy($key)
1604
  {
1605
    $results = array();
1606
1607
    foreach ($this->array as $a) {
1608
      if (\array_key_exists($key, $a) === true) {
1609 18
        $results[$a[$key]] = $a;
1610
      }
1611 18
    }
1612
1613 18
    return static::create($results);
1614
  }
1615
1616
  /**
1617
   * alias: for "Arrayy->searchIndex()"
1618
   *
1619
   * @see Arrayy::searchIndex()
1620
   *
1621
   * @param mixed $value <p>The value to search for.</p>
1622
   *
1623
   * @return mixed
1624 30
   */
1625
  public function indexOf($value)
1626 30
  {
1627
    return $this->searchIndex($value);
1628
  }
1629
1630
  /**
1631 30
   * Get everything but the last..$to items.
1632 30
   *
1633
   * @param int $to
1634
   *
1635 30
   * @return static <p>(Immutable)</p>
1636 3
   */
1637
  public function initial($to = 1)
1638
  {
1639
    $slice = count($this->array) - $to;
1640
1641 3
    return $this->firstsImmutable($slice);
1642
  }
1643
1644
  /**
1645 3
   * @param mixed $value
1646 3
   */
1647
  protected function internalGetArray(&$value)
1648 30
  {
1649
    if ($value instanceof self) {
1650 30
      $value &= $value->getArray();
1651
    } 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...
1652
      $value &= $value->jsonSerialize();
1653
    }
1654
  }
1655
1656
  /**
1657
   * Internal mechanics of remove method.
1658
   *
1659
   * @param string $key
1660 2
   *
1661
   * @return boolean
1662 2
   */
1663
  protected function internalRemove($key)
1664
  {
1665
    $path = explode($this->pathSeparator, (string)$key);
1666
1667
    // Crawl though the keys
1668
    while (count($path) > 1) {
1669
      $key = \array_shift($path);
1670
1671
      if (!$this->has($key)) {
1672 1
        return false;
1673
      }
1674 1
1675
      $this->array = &$this->array[$key];
1676
    }
1677
1678
    $key = \array_shift($path);
1679
1680
    unset($this->array[$key]);
1681
1682
    return true;
1683
  }
1684
1685 1
  /**
1686
   * Internal mechanic of set method.
1687
   *
1688 1
   * @param string $key
1689 1
   * @param mixed  $value
1690 1
   *
1691
   * @return bool
1692
   */
1693 1
  protected function internalSet($key, $value)
1694 1
  {
1695 1
    if ($key === null) {
1696 1
      return false;
1697
    }
1698
1699 1
    // init
1700
    $array =& $this->array;
1701
    $path = explode($this->pathSeparator, (string)$key);
1702
1703
    // Crawl through the keys
1704
    while (count($path) > 1) {
1705
      $key = \array_shift($path);
1706
1707 15
      // If the key doesn't exist at this depth, we will just create an empty array
1708
      // to hold the next value, allowing us to create the arrays to hold final
1709 15
      // values at the correct depth. Then we'll keep digging into the array.
1710 3
      if (!isset($array[$key]) || !is_array($array[$key])) {
1711
        $array[$key] = static::create(array());
1712
      }
1713 13
1714 13
      $array =& $array[$key];
1715 11
    }
1716
1717 3
    $array[\array_shift($path)] = $value;
1718
1719 3
    return true;
1720
  }
1721
1722
  /**
1723
   * Return an array with all elements found in input array.
1724
   *
1725
   * @param array $search
1726
   *
1727 88
   * @return static <p>(Immutable)</p>
1728
   */
1729 88
  public function intersection(array $search)
1730
  {
1731
    return static::create(\array_values(\array_intersect($this->array, $search)));
1732
  }
1733
1734
  /**
1735
   * Return a boolean flag which indicates whether the two input arrays have any common elements.
1736
   *
1737
   * @param array $search
1738
   *
1739
   * @return bool
1740
   */
1741
  public function intersects(array $search)
1742
  {
1743
    return count($this->intersection($search)->array) > 0;
1744
  }
1745
1746
  /**
1747
   * Invoke a function on all of an array's values.
1748
   *
1749 14
   * @param mixed $callable
1750
   * @param mixed $arguments
1751 14
   *
1752
   * @return static <p>(Immutable)</p>
1753
   */
1754
  public function invoke($callable, $arguments = array())
1755
  {
1756
    // If one argument given for each iteration, create an array for it.
1757
    if (!is_array($arguments)) {
1758
      $arguments = StaticArrayy::repeat($arguments, count($this->array))->getArray();
1759 5
    }
1760
1761 5
    // If the callable has arguments, pass them.
1762 2
    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...
1763
      $array = \array_map($callable, $this->array, $arguments);
1764
    } else {
1765 4
      $array = \array_map($callable, $this->array);
1766 4
    }
1767 2
1768
    return static::create($array);
1769 3
  }
1770
1771 2
  /**
1772
   * Check whether array is associative or not.
1773
   *
1774
   * @return bool <p>Returns true if associative, false otherwise.</p>
1775
   */
1776
  public function isAssoc()
1777
  {
1778
    if ($this->isEmpty()) {
1779 1
      return false;
1780
    }
1781 1
1782
    foreach ($this->keys()->getArray() as $key) {
1783
      if (!is_string($key)) {
1784
        return false;
1785
      }
1786
    }
1787
1788
    return true;
1789
  }
1790
1791
  /**
1792
   * Check whether the array is empty or not.
1793
   *
1794
   * @return bool <p>Returns true if empty, false otherwise.</p>
1795
   */
1796
  public function isEmpty()
1797 25
  {
1798
    return !$this->array;
1799 25
  }
1800
1801
  /**
1802
   * Check if the current array is equal to the given "$array" or not.
1803
   *
1804
   * @param array $array
1805
   *
1806
   * @return bool
1807
   */
1808
  public function isEqual(array $array)
1809
  {
1810
    return ($this->array === $array);
1811
  }
1812
1813 4
  /**
1814
   * Check if the current array is a multi-array.
1815 4
   *
1816
   * @return bool
1817 4
   */
1818
  public function isMultiArray()
1819
  {
1820
    return !(count($this->array) === count($this->array, COUNT_RECURSIVE));
1821
  }
1822
1823
  /**
1824
   * Check whether array is numeric or not.
1825 4
   *
1826
   * @return bool <p>Returns true if numeric, false otherwise.</p>
1827 4
   */
1828
  public function isNumeric()
1829
  {
1830
    if ($this->isEmpty()) {
1831
      return false;
1832
    }
1833
1834
    foreach ($this->keys() as $key) {
1835
      if (!is_int($key)) {
1836
        return false;
1837 13
      }
1838
    }
1839 13
1840 1
    return true;
1841
  }
1842
1843 12
  /**
1844 8
   * Check if the current array is sequential [0, 1, 2, 3, 4, 5 ...] or not.
1845
   *
1846 8
   * @return bool
1847 1
   */
1848 1
  public function isSequential()
1849 7
  {
1850
    return \array_keys($this->array) === range(0, count($this->array) - 1);
1851
  }
1852 8
1853 8
  /**
1854 4
   * @return array
1855 4
   */
1856
  public function jsonSerialize()
1857
  {
1858 12
    return $this->getArray();
1859
  }
1860
1861
  /**
1862
   * Get all keys from the current array.
1863
   *
1864
   * @return static <p>(Immutable)</p>
1865
   */
1866
  public function keys()
1867
  {
1868 13
    return static::create(\array_keys($this->array));
1869
  }
1870 13
1871 1
  /**
1872
   * Sort an array by key in reverse order.
1873
   *
1874 12
   * @param int $sort_flags [optional] <p>
1875 8
   *                        You may modify the behavior of the sort using the optional
1876
   *                        parameter sort_flags, for details
1877 8
   *                        see sort.
1878 1
   *                        </p>
1879 1
   *
1880 7
   * @return static <p>(Mutable) Return this Arrayy object.</p>
1881
   */
1882
  public function krsort($sort_flags = null)
1883 8
  {
1884 8
    krsort($this->array, $sort_flags);
1885 4
1886 4
    return $this;
1887
  }
1888
1889 12
  /**
1890
   * Get the last value from the current array.
1891
   *
1892
   * @return mixed <p>Return null if there wasn't a element.</p>
1893
   */
1894
  public function last()
1895
  {
1896
    return $this->pop();
1897
  }
1898
1899
  /**
1900
   * Get the last value(s) from the current array.
1901 10
   *
1902
   * @param int|null $number
1903 10
   *
1904
   * @return static <p>(Immutable)</p>
1905
   */
1906
  public function lastsImmutable($number = null)
1907
  {
1908
    if ($this->isEmpty()) {
1909
      return static::create();
1910
    }
1911
1912
    if ($number === null) {
1913
      $poppedValue = $this->pop();
1914 4
1915
      if ($poppedValue === null) {
1916 4
        $poppedValue = array($poppedValue);
1917
      } else {
1918 4
        $poppedValue = (array)$poppedValue;
1919
      }
1920
1921
      $arrayy = static::create($poppedValue);
1922
    } else {
1923
      $number = (int)$number;
1924
      $arrayy = $this->rest(-$number);
1925
    }
1926
1927
    return $arrayy;
1928 15
  }
1929
1930 15
  /**
1931 2
   * Get the last value(s) from the current array.
1932
   *
1933
   * @param int|null $number
1934
   *
1935 13
   * @return static <p>(Mutable)</p>
1936
   */
1937 13
  public function lastsMutable($number = null)
1938 13
  {
1939
    if ($this->isEmpty()) {
1940 13
      return $this;
1941 7
    }
1942
1943 9
    if ($number === null) {
1944
      $poppedValue = $this->pop();
1945 7
1946
      if ($poppedValue === null) {
1947
        $poppedValue = array($poppedValue);
1948
      } else {
1949
        $poppedValue = (array)$poppedValue;
1950
      }
1951
1952
      $this->array = static::create($poppedValue)->array;
1953
    } else {
1954
      $number = (int)$number;
1955 14
      $this->array = $this->rest(-$number)->array;
1956
    }
1957 14
1958 2
    return $this;
1959
  }
1960
1961
  /**
1962 12
   * Count the values from the current array.
1963
   *
1964 12
   * alias: for "Arrayy->size()"
1965 12
   *
1966
   * @see Arrayy::size()
1967 12
   *
1968 9
   * @return int
1969
   */
1970 5
  public function length()
1971
  {
1972 4
    return $this->size();
1973
  }
1974
1975
  /**
1976
   * Apply the given function to the every element of the array,
1977
   * collecting the results.
1978
   *
1979
   * @param callable $callable
1980 10
   *
1981
   * @return static <p>(Immutable) Arrayy object with modified elements.</p>
1982 10
   */
1983 1
  public function map($callable)
1984
  {
1985
    $result = \array_map($callable, $this->array);
1986 9
1987
    return static::create($result);
1988
  }
1989
1990
  /**
1991
   * Check if all items in current array match a truth test.
1992
   *
1993
   * @param \Closure $closure
1994
   *
1995
   * @return bool
1996
   */
1997 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...
1998
  {
1999 25
    if (count($this->array) === 0) {
2000
      return false;
2001 25
    }
2002 4
2003 4
    // init
2004 21
    $array = $this->array;
2005
2006
    foreach ($array as $key => $value) {
2007 25
      $value = $closure($value, $key);
2008
2009
      if ($value === false) {
2010
        return false;
2011
      }
2012
    }
2013
2014
    return true;
2015
  }
2016
2017
  /**
2018
   * Check if any item in the current array matches a truth test.
2019
   *
2020
   * @param \Closure $closure
2021 16
   *
2022
   * @return bool
2023 16
   */
2024 4 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...
2025 4
  {
2026 12
    if (count($this->array) === 0) {
2027
      return false;
2028
    }
2029 16
2030
    // init
2031
    $array = $this->array;
2032
2033
    foreach ($array as $key => $value) {
2034
      $value = $closure($value, $key);
2035
2036
      if ($value === true) {
2037
        return true;
2038
      }
2039
    }
2040
2041
    return false;
2042 16
  }
2043
2044 16
  /**
2045 4
   * Get the max value from an array.
2046 4
   *
2047 12
   * @return mixed
2048
   */
2049
  public function max()
2050 16
  {
2051
    if ($this->count() === 0) {
2052
      return false;
2053
    }
2054
2055
    return max($this->array);
2056
  }
2057
2058
  /**
2059
   * Merge the new $array into the current array.
2060
   *
2061
   * - keep key,value from the current array, also if the index is in the new $array
2062
   *
2063
   * @param array $array
2064 17
   * @param bool  $recursive
2065
   *
2066 17
   * @return static <p>(Immutable)</p>
2067 4
   */
2068 4 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...
2069 13
  {
2070
    if (true === $recursive) {
2071
      $result = \array_replace_recursive($this->array, $array);
2072 17
    } else {
2073
      $result = \array_replace($this->array, $array);
2074
    }
2075
2076
    return static::create($result);
2077
  }
2078
2079
  /**
2080 10
   * Merge the new $array into the current array.
2081
   *
2082 10
   * - replace duplicate assoc-keys from the current array with the key,values from the new $array
2083 1
   * - create new indexes
2084
   *
2085
   * @param array $array
2086 9
   * @param bool  $recursive
2087
   *
2088
   * @return static <p>(Immutable)</p>
2089
   */
2090 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...
2091
  {
2092
    if (true === $recursive) {
2093
      $result = \array_merge_recursive($this->array, $array);
2094
    } else {
2095
      $result = \array_merge($this->array, $array);
2096
    }
2097
2098
    return static::create($result);
2099 1
  }
2100
2101 1
  /**
2102
   * Merge the the current array into the $array.
2103 1
   *
2104 1
   * - use key,value from the new $array, also if the index is in the current array
2105 1
   *
2106 1
   * @param array $array
2107 1
   * @param bool  $recursive
2108 1
   *
2109 1
   * @return static <p>(Immutable)</p>
2110 1
   */
2111 1 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...
2112 1
  {
2113 1
    if (true === $recursive) {
2114 1
      $result = \array_replace_recursive($array, $this->array);
2115 1
    } else {
2116 1
      $result = \array_replace($array, $this->array);
2117 1
    }
2118 1
2119 1
    return static::create($result);
2120 1
  }
2121
2122
  /**
2123
   * Merge the current array into the new $array.
2124 1
   *
2125
   * - replace duplicate assoc-keys from new $array with the key,values from the current array
2126
   * - create new indexes
2127
   *
2128
   * @param array $array
2129
   * @param bool  $recursive
2130
   *
2131
   * @return static <p>(Immutable)</p>
2132
   */
2133 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...
2134
  {
2135
    if (true === $recursive) {
2136
      $result = \array_merge_recursive($array, $this->array);
2137
    } else {
2138
      $result = \array_merge($array, $this->array);
2139
    }
2140
2141
    return static::create($result);
2142
  }
2143
2144
  /**
2145
   * Get the min value from an array.
2146
   *
2147
   * @return mixed
2148
   */
2149 4
  public function min()
2150
  {
2151 4
    if ($this->count() === 0) {
2152
      return false;
2153 4
    }
2154
2155
    return min($this->array);
2156
  }
2157
2158
  /**
2159
   * Move an array element to a new index.
2160
   *
2161 16
   * cherry-picked from: http://stackoverflow.com/questions/12624153/move-an-array-element-to-a-new-index-in-php
2162
   *
2163 16
   * @param int|string $from
2164
   * @param int|string $to
2165
   *
2166
   * @return static <p>(Immutable)</p>
2167
   */
2168
  public function moveElement($from, $to)
2169
  {
2170
    $array = $this->array;
2171
2172
    if (is_int($from)) {
2173
      $tmp = \array_splice($array, $from, 1);
2174 8
      \array_splice($array, $to, 0, $tmp);
2175
      $output = $array;
2176 8
    } elseif (is_string($from)) {
2177 8
      $indexToMove = \array_search($from, \array_keys($array), true);
2178 8
      $itemToMove = $array[$from];
2179
      \array_splice($array, $indexToMove, 1);
2180 1
      $i = 0;
2181
      $output = array();
2182
      foreach ($array as $key => $item) {
2183 8
        if ($i == $to) {
2184
          $output[$from] = $itemToMove;
2185
        }
2186
        $output[$key] = $item;
2187
        $i++;
2188
      }
2189
    } else {
2190
      $output = array();
2191 4
    }
2192
2193 4
    return static::create($output);
2194 4
  }
2195 4
2196 4
  /**
2197
   * Get a subset of the items from the given array.
2198 4
   *
2199
   * @param mixed[] $keys
2200
   *
2201
   * @return static <p>(Immutable)</p>
2202
   */
2203
  public function only(array $keys)
2204
  {
2205
    $array = $this->array;
2206
2207
    return static::create(\array_intersect_key($array, \array_flip($keys)));
2208 17
  }
2209
2210 17
  /**
2211
   * Pad array to the specified size with a given value.
2212
   *
2213
   * @param int   $size  <p>Size of the result array.</p>
2214 17
   * @param mixed $value <p>Empty value by default.</p>
2215 14
   *
2216
   * @return static <p>(Immutable) Arrayy object padded to $size with $value.</p>
2217 14
   */
2218
  public function pad($size, $value)
2219
  {
2220 5
    $result = \array_pad($this->array, $size, $value);
2221 5
2222
    return static::create($result);
2223 5
  }
2224
2225
  /**
2226
   * Pop a specified value off the end of the current array.
2227
   *
2228
   * @return mixed <p>(Mutable) The popped element from the current array.</p>
2229
   */
2230
  public function pop()
2231
  {
2232
    return \array_pop($this->array);
2233 4
  }
2234
2235 4
  /**
2236
   * Prepend a value to the current array.
2237 4
   *
2238
   * @param mixed $value
2239
   * @param mixed $key
2240
   *
2241 4
   * @return static <p>(Mutable) Return this Arrayy object, with the prepended value.</p>
2242
   */
2243
  public function prepend($value, $key = null)
2244
  {
2245
    if ($key === null) {
2246
      \array_unshift($this->array, $value);
2247
    } else {
2248
      /** @noinspection AdditionOperationOnArraysInspection */
2249
      $this->array = array($key => $value) + $this->array;
2250
    }
2251
2252
    return $this;
2253 14
  }
2254
2255 14
  /**
2256 14
   * Push one or more values onto the end of array at once.
2257
   *
2258 14
   * @return static <p>(Mutable) Return this Arrayy object, with pushed elements to the end of array.</p>
2259 3
   */
2260 3 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...
2261 3
  {
2262 3
    if (func_num_args()) {
2263
      $args = \array_merge(array(&$this->array), func_get_args());
2264 3
      call_user_func_array('array_push', $args);
2265 3
    }
2266
2267
    return $this;
2268 11
  }
2269
2270 11
  /**
2271
   * Get a random value from the current array.
2272
   *
2273
   * @param null|int $number <p>How many values you will take?</p>
2274
   *
2275
   * @return static <p>(Immutable)</p>
2276
   */
2277
  public function randomImmutable($number = null)
2278
  {
2279
    if ($this->count() === 0) {
2280 17
      return static::create();
2281
    }
2282 17
2283 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...
2284
      $arrayRandValue = array($this->array[\array_rand($this->array)]);
2285
2286 17
      return static::create($arrayRandValue);
2287 7
    }
2288 7
2289
    $arrayTmp = $this->array;
2290 7
    shuffle($arrayTmp);
2291
2292
    return static::create($arrayTmp)->firstsImmutable($number);
2293 11
  }
2294
2295 11
  /**
2296
   * Pick a random key/index from the keys of this array.
2297
   *
2298
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
2299
   *
2300
   * @throws \RangeException If array is empty
2301
   */
2302
  public function randomKey()
2303 4
  {
2304
    $result = $this->randomKeys(1);
2305 4
2306
    if (!isset($result[0])) {
2307 4
      $result[0] = null;
2308
    }
2309
2310
    return $result[0];
2311 4
  }
2312
2313
  /**
2314
   * Pick a given number of random keys/indexes out of this array.
2315
   *
2316
   * @param int $number <p>The number of keys/indexes (should be <= $this->count())</p>
2317
   *
2318
   * @return static <p>(Immutable)</p>
2319
   *
2320
   * @throws \RangeException If array is empty
2321 7
   */
2322
  public function randomKeys($number)
2323 7
  {
2324
    $number = (int)$number;
2325 7
    $count = $this->count();
2326
2327
    if ($number === 0 || $number > $count) {
2328
      throw new \RangeException(
2329
          sprintf(
2330
              'Number of requested keys (%s) must be equal or lower than number of elements in this array (%s)',
2331
              $number,
2332
              $count
2333
          )
2334
      );
2335
    }
2336
2337
    $result = (array)\array_rand($this->array, $number);
2338 9
2339
    return static::create($result);
2340 9
  }
2341 9
2342 9
  /**
2343 2
   * Get a random value from the current array.
2344 1
   *
2345 1
   * @param null|int $number <p>How many values you will take?</p>
2346 2
   *
2347 9
   * @return static <p>(Mutable)</p>
2348
   */
2349 9
  public function randomMutable($number = null)
2350
  {
2351
    if ($this->count() === 0) {
2352
      return static::create();
2353
    }
2354
2355 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...
2356
      $arrayRandValue = array($this->array[\array_rand($this->array)]);
2357
      $this->array = $arrayRandValue;
2358
2359
      return $this;
2360 4
    }
2361
2362 4
    shuffle($this->array);
2363
2364 4
    return $this->firstsMutable($number);
2365
  }
2366
2367 4
  /**
2368
   * Pick a random value from the values of this array.
2369
   *
2370 4
   * @return mixed <p>Get a random value or null if there wasn't a value.</p>
2371
   */
2372
  public function randomValue()
2373
  {
2374
    $result = $this->randomImmutable();
2375
2376
    if (!isset($result[0])) {
2377
      $result[0] = null;
2378 9
    }
2379
2380 9
    return $result[0];
2381
  }
2382 9
2383
  /**
2384
   * Pick a given number of random values out of this array.
2385
   *
2386
   * @param int $number
2387
   *
2388
   * @return static <p>(Mutable)</p>
2389
   */
2390
  public function randomValues($number)
2391
  {
2392 1
    $number = (int)$number;
2393
2394 1
    return $this->randomMutable($number);
2395
  }
2396 1
2397 1
  /**
2398 1
   * Get a random value from an array, with the ability to skew the results.
2399 1
   *
2400 1
   * Example: randomWeighted(['foo' => 1, 'bar' => 2]) has a 66% chance of returning bar.
2401
   *
2402 1
   * @param array    $array
2403
   * @param null|int $number <p>How many values you will take?</p>
2404
   *
2405
   * @return static <p>(Immutable)</p>
2406
   */
2407
  public function randomWeighted(array $array, $number = null)
2408
  {
2409
    $options = array();
2410
    foreach ($array as $option => $weight) {
2411
      if ($this->searchIndex($option) !== false) {
2412 18
        for ($i = 0; $i < $weight; ++$i) {
2413
          $options[] = $option;
2414
        }
2415 18
      }
2416
    }
2417
2418
    return $this->mergeAppendKeepIndex($options)->randomImmutable($number);
2419
  }
2420
2421
  /**
2422
   * Reduce the current array via callable e.g. anonymous-function.
2423 18
   *
2424
   * @param mixed $callable
2425 18
   * @param array $init
2426
   *
2427
   * @return static <p>(Immutable)</p>
2428
   */
2429
  public function reduce($callable, array $init = array())
2430
  {
2431
    $result = \array_reduce($this->array, $callable, $init);
2432
2433 7
    if ($result === null) {
2434
      $this->array = array();
2435 7
    } else {
2436 7
      $this->array = (array)$result;
2437
    }
2438 7
2439
    return static::create($this->array);
2440
  }
2441
2442
  /**
2443
   * Create a numerically re-indexed Arrayy object.
2444
   *
2445
   * @return static <p>(Mutable) Return this Arrayy object, with re-indexed array-elements.</p>
2446 7
   */
2447
  public function reindex()
2448 7
  {
2449 7
    $this->array = \array_values($this->array);
2450
2451 7
    return $this;
2452
  }
2453
2454
  /**
2455
   * Return all items that fail the truth test.
2456
   *
2457
   * @param \Closure $closure
2458
   *
2459
   * @return static <p>(Immutable)</p>
2460
   */
2461 7 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...
2462
  {
2463 7
    $filtered = array();
2464 7
2465 6
    foreach ($this->array as $key => $value) {
2466 6
      if (!$closure($value, $key)) {
2467
        $filtered[$key] = $value;
2468
      }
2469 6
    }
2470 6
2471 7
    return static::create($filtered);
2472
  }
2473 7
2474 7
  /**
2475 7
   * Remove a value from the current array (optional using dot-notation).
2476
   *
2477 7
   * @param mixed $key
2478
   *
2479
   * @return static <p>(Immutable)</p>
2480
   */
2481
  public function remove($key)
2482
  {
2483
    // Recursive call
2484
    if (is_array($key)) {
2485
      foreach ($key as $k) {
2486
        $this->internalRemove($k);
2487 1
      }
2488
2489 1
      return static::create($this->array);
2490 1
    }
2491
2492
    $this->internalRemove($key);
2493 1
2494
    return static::create($this->array);
2495
  }
2496
2497
  /**
2498
   * Remove the first value from the current array.
2499
   *
2500
   * @return static <p>(Immutable)</p>
2501
   */
2502
  public function removeFirst()
2503
  {
2504
    $tmpArray = $this->array;
2505 2
    \array_shift($tmpArray);
2506
2507 2
    return static::create($tmpArray);
2508
  }
2509 2
2510
  /**
2511
   * Remove the last value from the current array.
2512
   *
2513
   * @return static <p>(Immutable)</p>
2514
   */
2515
  public function removeLast()
2516
  {
2517
    $tmpArray = $this->array;
2518
    \array_pop($tmpArray);
2519 2
2520
    return static::create($tmpArray);
2521 2
  }
2522
2523 2
  /**
2524
   * Removes a particular value from an array (numeric or associative).
2525
   *
2526
   * @param mixed $value
2527
   *
2528
   * @return static <p>(Immutable)</p>
2529
   */
2530
  public function removeValue($value)
2531
  {
2532
    $isNumericArray = true;
2533 2
    foreach ($this->array as $key => $item) {
2534
      if ($item === $value) {
2535 2
        if (!is_int($key)) {
2536
          $isNumericArray = false;
2537 2
        }
2538
        unset($this->array[$key]);
2539
      }
2540
    }
2541
2542
    if ($isNumericArray) {
2543
      $this->array = \array_values($this->array);
2544
    }
2545
2546
    return static::create($this->array);
2547 1
  }
2548
2549 1
  /**
2550 1
   * Generate array of repeated arrays.
2551
   *
2552 1
   * @param int $times <p>How many times has to be repeated.</p>
2553
   *
2554
   * @return Arrayy
2555
   */
2556
  public function repeat($times)
2557
  {
2558
    if ($times === 0) {
2559
      return new static();
2560
    }
2561
2562
    return static::create(\array_fill(0, (int)$times, $this->array));
2563 3
  }
2564
2565 3
  /**
2566 3
   * Replace a key with a new key/value pair.
2567
   *
2568 3
   * @param $replace
2569 3
   * @param $key
2570 3
   * @param $value
2571
   *
2572 3
   * @return static <p>(Immutable)</p>
2573
   */
2574
  public function replace($replace, $key, $value)
2575
  {
2576
    $this->remove($replace);
2577
2578
    return $this->set($key, $value);
2579
  }
2580
2581
  /**
2582
   * Create an array using the current array as values and the other array as keys.
2583 1
   *
2584
   * @param array $keys <p>An array of keys.</p>
2585 1
   *
2586
   * @return static <p>(Immutable) Arrayy object with keys from the other array.</p>
2587 1
   */
2588
  public function replaceAllKeys(array $keys)
2589 1
  {
2590
    $result = \array_combine($keys, $this->array);
2591 1
2592
    return static::create($result);
2593
  }
2594
2595
  /**
2596
   * Create an array using the current array as keys and the other array as values.
2597
   *
2598
   * @param array $array <p>An array o values.</p>
2599
   *
2600
   * @return static <p>(Immutable) Arrayy object with values from the other array.</p>
2601 15
   */
2602
  public function replaceAllValues(array $array)
2603 15
  {
2604
    $result = \array_combine($this->array, $array);
2605 15
2606
    return static::create($result);
2607
  }
2608
2609
  /**
2610
   * Replace the keys in an array with another set.
2611
   *
2612
   * @param array $keys <p>An array of keys matching the array's size</p>
2613 8
   *
2614
   * @return static <p>(Immutable)</p>
2615 8
   */
2616
  public function replaceKeys(array $keys)
2617 8
  {
2618
    $values = \array_values($this->array);
2619
    $result = \array_combine($keys, $values);
2620
2621
    return static::create($result);
2622
  }
2623
2624
  /**
2625
   * Replace the first matched value in an array.
2626
   *
2627
   * @param mixed $search
2628
   * @param mixed $replacement
2629
   *
2630
   * @return static <p>(Immutable)</p>
2631 4
   */
2632
  public function replaceOneValue($search, $replacement = '')
2633 4
  {
2634
    $array = $this->array;
2635 4
    $key = \array_search($search, $array, true);
2636
2637
    if ($key !== false) {
2638
      $array[$key] = $replacement;
2639
    }
2640
2641
    return static::create($array);
2642
  }
2643
2644
  /**
2645 20
   * Replace values in the current array.
2646
   *
2647 20
   * @param string $search      <p>The string to replace.</p>
2648
   * @param string $replacement <p>What to replace it with.</p>
2649
   *
2650
   * @return static <p>(Immutable)</p>
2651
   */
2652
  public function replaceValues($search, $replacement = '')
2653
  {
2654
    $array = $this->each(
2655
        function ($value) use ($search, $replacement) {
2656
          return UTF8::str_replace($search, $replacement, $value);
2657 9
        }
2658
    );
2659
2660 9
    return $array;
2661
  }
2662 9
2663
  /**
2664
   * Get the last elements from index $from until the end of this array.
2665
   *
2666
   * @param int $from
2667 9
   *
2668 1
   * @return static <p>(Immutable)</p>
2669 1
   */
2670
  public function rest($from = 1)
2671 9
  {
2672 7
    $tmpArray = $this->array;
2673 7
2674
    return static::create(\array_splice($tmpArray, $from));
2675
  }
2676 9
2677
  /**
2678
   * Return the array in the reverse order.
2679
   *
2680
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2681
   */
2682
  public function reverse()
2683
  {
2684
    $this->array = \array_reverse($this->array);
2685
2686
    return $this;
2687 17
  }
2688
2689 17
  /**
2690
   * Sort an array in reverse order.
2691 17
   *
2692
   * @param int $sort_flags [optional] <p>
2693
   *                        You may modify the behavior of the sort using the optional
2694
   *                        parameter sort_flags, for details
2695
   *                        see sort.
2696
   *                        </p>
2697
   *
2698
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2699
   */
2700
  public function rsort($sort_flags = null)
2701
  {
2702
    rsort($this->array, $sort_flags);
2703
2704 11
    return $this;
2705
  }
2706
2707 11
  /**
2708 4
   * Search for the first index of the current array via $value.
2709 4
   *
2710
   * @param mixed $value
2711 11
   *
2712
   * @return int|float|string
2713
   */
2714
  public function searchIndex($value)
2715
  {
2716
    return \array_search($value, $this->array, true);
2717
  }
2718
2719 4
  /**
2720
   * Search for the value of the current array via $index.
2721 4
   *
2722
   * @param mixed $index
2723
   *
2724
   * @return static <p>(Immutable) Will return a empty Arrayy if the value wasn't found.</p>
2725
   */
2726
  public function searchValue($index)
2727
  {
2728
    // init
2729 1
    $return = array();
2730
2731 1
    if ($this->isEmpty()) {
2732
      return static::create();
2733 1
    }
2734
2735 1
    // php cast "bool"-index into "int"-index
2736
    if ((bool)$index === $index) {
2737
      $index = (int)$index;
2738
    }
2739
2740
    if (\array_key_exists($index, $this->array) === true) {
2741
      $return = array($this->array[$index]);
2742
    }
2743 93
2744
2745 93
    return static::create($return);
2746
  }
2747
2748
  /**
2749
   * Set a value for the current array (optional using dot-notation).
2750
   *
2751
   * @param string $key   <p>The key to set.</p>
2752
   * @param mixed  $value <p>Its value.</p>
2753
   *
2754
   * @return static <p>(Immutable)</p>
2755
   */
2756
  public function set($key, $value)
2757 4
  {
2758
    $this->internalSet($key, $value);
2759 4
2760
    return static::create($this->array);
2761 4
  }
2762
2763
  /**
2764
   * Get a value from a array and set it if it was not.
2765
   *
2766
   * WARNING: this method only set the value, if the $key is not already set
2767
   *
2768
   * @param string $key      <p>The key</p>
2769
   * @param mixed  $fallback <p>The default value to set if it isn't.</p>
2770
   *
2771
   * @return mixed <p>(Mutable)</p>
2772
   */
2773
  public function setAndGet($key, $fallback = null)
2774 19
  {
2775
    // If the key doesn't exist, set it.
2776 19
    if (!$this->has($key)) {
2777
      $this->array = $this->set($key, $fallback)->getArray();
2778 19
    }
2779
2780
    return $this->get($key);
2781
  }
2782
2783
  /**
2784
   * Shifts a specified value off the beginning of array.
2785
   *
2786
   * @return mixed <p>(Mutable) A shifted element from the current array.</p>
2787
   */
2788
  public function shift()
2789
  {
2790
    return \array_shift($this->array);
2791
  }
2792
2793 18
  /**
2794
   * Shuffle the current array.
2795 18
   *
2796
   * @return static <p>(Immutable)</p>
2797 18
   */
2798
  public function shuffle()
2799
  {
2800
    $array = $this->array;
2801
2802
    shuffle($array);
2803
2804
    return static::create($array);
2805
  }
2806
2807
  /**
2808 1
   * Get the size of an array.
2809
   *
2810 1
   * @return int
2811
   */
2812
  public function size()
2813
  {
2814
    return count($this->array);
2815
  }
2816
2817
  /**
2818
   * Extract a slice of the array.
2819
   *
2820
   * @param int      $offset       <p>Slice begin index.</p>
2821 1
   * @param int|null $length       <p>Length of the slice.</p>
2822
   * @param bool     $preserveKeys <p>Whether array keys are preserved or no.</p>
2823 1
   *
2824
   * @return static <p>A slice of the original array with length $length.</p>
2825
   */
2826
  public function slice($offset, $length = null, $preserveKeys = false)
2827
  {
2828
    $result = \array_slice($this->array, $offset, $length, $preserveKeys);
2829
2830
    return static::create($result);
2831
  }
2832
2833
  /**
2834
   * Sort the current array and optional you can keep the keys.
2835
   *
2836
   * @param integer $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2837
   * @param integer $strategy  <p>sort_flags => use e.g.: <strong>SORT_REGULAR</strong> (default) or
2838
   *                           <strong>SORT_NATURAL</strong></p>
2839 1
   * @param bool    $keepKeys
2840
   *
2841 1
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2842 1
   */
2843
  public function sort($direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2844
  {
2845 1
    $this->sorting($this->array, $direction, $strategy, $keepKeys);
2846 1
2847
    return $this;
2848 1
  }
2849 1
2850
  /**
2851 1
   * Sort the current array by key.
2852
   *
2853 1
   * @link http://php.net/manual/en/function.ksort.php
2854
   * @link http://php.net/manual/en/function.krsort.php
2855 1
   *
2856 1
   * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2857 1
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2858
   *                              <strong>SORT_NATURAL</strong></p>
2859
   *
2860
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2861 1
   */
2862
  public function sortKeys($direction = SORT_ASC, $strategy = SORT_REGULAR)
2863 1
  {
2864
    $this->sorterKeys($this->array, $direction, $strategy);
2865
2866
    return $this;
2867
  }
2868
2869
  /**
2870
   * Sort the current array by value.
2871
   *
2872
   * @param int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2873
   * @param int $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2874
   *
2875 18
   * @return static <p>(Mutable)</p>
2876
   */
2877 18
  public function sortValueKeepIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2878
  {
2879
    return $this->sort($direction, $strategy, true);
2880 18
  }
2881 18
2882 6
  /**
2883 6
   * Sort the current array by value.
2884 13
   *
2885 13
   * @param int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2886 13
   * @param int $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2887 13
   *
2888 13
   * @return static <p>(Mutable)</p>
2889
   */
2890 18
  public function sortValueNewIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2891
  {
2892
    return $this->sort($direction, $strategy, false);
2893
  }
2894
2895
  /**
2896
   * Sort a array by value, by a closure or by a property.
2897
   *
2898
   * - If the sorter is null, the array is sorted naturally.
2899
   * - Associative (string) keys will be maintained, but numeric keys will be re-indexed.
2900
   *
2901
   * @param null       $sorter
2902 19
   * @param string|int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2903
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2904 19
   *                              <strong>SORT_NATURAL</strong></p>
2905
   *
2906 19
   * @return static <p>(Immutable)</p>
2907 19
   */
2908 19
  public function sorter($sorter = null, $direction = SORT_ASC, $strategy = SORT_REGULAR)
2909
  {
2910
    $array = (array)$this->array;
2911 19
    $direction = $this->getDirection($direction);
2912 19
2913 9
    // Transform all values into their results.
2914 5
    if ($sorter) {
2915 5
      $arrayy = static::create($array);
2916 4
2917
      $that = $this;
2918 9
      $results = $arrayy->each(
2919 10
          function ($value) use ($sorter, $that) {
2920 10
            return is_callable($sorter) ? $sorter($value) : $that->get($sorter, null, $value);
2921 10
          }
2922 10
      );
2923 4
2924 4
      $results = $results->getArray();
2925 6
    } else {
2926
      $results = $array;
2927 10
    }
2928
2929 19
    // Sort by the results and replace by original values
2930
    \array_multisort($results, $direction, $strategy, $array);
2931
2932
    return static::create($array);
2933
  }
2934
2935
  /**
2936
   * sorting keys
2937
   *
2938
   * @param array $elements
2939
   * @param int   $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2940 1
   * @param int   $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2941
   *
2942 1
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2943
   */
2944 1
  protected function sorterKeys(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR)
2945 1
  {
2946 1
    $direction = $this->getDirection($direction);
2947 1
2948 1
    switch ($direction) {
2949 1
      case 'desc':
2950
      case SORT_DESC:
2951
        krsort($elements, $strategy);
2952 1
        break;
2953
      case 'asc':
2954
      case SORT_ASC:
2955
      default:
2956
        ksort($elements, $strategy);
2957
    }
2958
2959
    return $this;
2960 1
  }
2961
2962 1
  /**
2963
   * @param array      &$elements
2964 1
   * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2965 1
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2966
   *                              <strong>SORT_NATURAL</strong></p>
2967
   * @param bool       $keepKeys
2968 1
   *
2969
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2970 1
   */
2971
  protected function sorting(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2972
  {
2973
    $direction = $this->getDirection($direction);
2974
2975
    if (!$strategy) {
2976
      $strategy = SORT_REGULAR;
2977
    }
2978
2979
    switch ($direction) {
2980
      case 'desc':
2981 1
      case SORT_DESC:
2982
        if ($keepKeys) {
2983 1
          arsort($elements, $strategy);
2984
        } else {
2985 1
          rsort($elements, $strategy);
2986
        }
2987 1
        break;
2988
      case 'asc':
2989
      case SORT_ASC:
2990
      default:
2991
        if ($keepKeys) {
2992
          asort($elements, $strategy);
2993
        } else {
2994
          sort($elements, $strategy);
2995 142
        }
2996
    }
2997 142
2998
    return $this;
2999
  }
3000
3001
  /**
3002
   * Split an array in the given amount of pieces.
3003
   *
3004
   * @param int  $numberOfPieces
3005
   * @param bool $keepKeys
3006
   *
3007
   * @return static <p>(Immutable)</p>
3008 6
   */
3009
  public function split($numberOfPieces = 2, $keepKeys = false)
3010 6
  {
3011
    $arrayCount = $this->count();
3012
3013
    if ($arrayCount === 0) {
3014
      $result = array();
3015
    } else {
3016
      $numberOfPieces = (int)$numberOfPieces;
3017
      $splitSize = (int)ceil($arrayCount / $numberOfPieces);
3018
      $result = \array_chunk($this->array, $splitSize, $keepKeys);
3019
    }
3020 19
3021
    return static::create($result);
3022 19
  }
3023
3024
  /**
3025
   * Stripe all empty items.
3026
   *
3027
   * @return static <p>(Immutable)</p>
3028
   */
3029
  public function stripEmpty()
3030 9
  {
3031
    return $this->filter(
3032 9
        function ($item) {
3033 9
          if ($item === null) {
3034
            return false;
3035 8
          }
3036 8
3037 8
          return (bool)trim((string)$item);
3038
        }
3039 8
    );
3040 9
  }
3041 9
3042 9
  /**
3043
   * Swap two values between positions by key.
3044 9
   *
3045
   * @param string|int $swapA <p>a key in the array</p>
3046
   * @param string|int $swapB <p>a key in the array</p>
3047 9
   *
3048
   * @return static <p>(Immutable)</p>
3049
   */
3050 9
  public function swap($swapA, $swapB)
3051
  {
3052
    $array = $this->array;
3053
3054
    list($array[$swapA], $array[$swapB]) = array($array[$swapB], $array[$swapA]);
3055
3056
    return static::create($array);
3057
  }
3058 9
3059
  /**
3060
   * alias: for "Arrayy->getArray()"
3061 9
   *
3062
   * @see Arrayy::getArray()
3063 9
   */
3064 9
  public function toArray()
3065 9
  {
3066 8
    return $this->getArray();
3067 8
  }
3068 8
3069
  /**
3070 8
   * Convert the current array to JSON.
3071 9
   *
3072 9
   * @param null|int $options [optional] <p>e.g. JSON_PRETTY_PRINT</p>
3073 9
   * @param int      $depth   [optional] <p>Set the maximum depth. Must be greater than zero.</p>
3074
   *
3075 9
   * @return string
3076
   */
3077
  public function toJson($options = null, $depth = 512)
3078 9
  {
3079
    return UTF8::json_encode($this->array, $options, $depth);
3080
  }
3081 9
3082
  /**
3083
   * Implodes array to a string with specified separator.
3084
   *
3085
   * @param string $separator [optional] <p>The element's separator.</p>
3086
   *
3087
   * @return string <p>The string representation of array, separated by ",".</p>
3088
   */
3089
  public function toString($separator = ',')
3090
  {
3091 9
    return $this->implode($separator);
3092
  }
3093 9
3094
  /**
3095
   * Return a duplicate free copy of the current array.
3096
   *
3097
   * @return static <p>(Mutable)</p>
3098
   */
3099
  public function unique()
3100
  {
3101 4
    // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array
3102
3103 4
    $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...
3104 4
        $this->array,
3105 4
        function ($resultArray, $value) {
3106 4
          if (!in_array($value, $resultArray, true)) {
3107
            $resultArray[] = $value;
3108 4
          }
3109
3110
          return $resultArray;
3111
        },
3112
        array()
3113
    );
3114
3115 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...
3116 2
      $this->array = array();
3117
    } else {
3118 2
      $this->array = (array)$this->array;
3119
    }
3120
3121
    return $this;
3122
  }
3123
3124
  /**
3125
   * Return a duplicate free copy of the current array. (with the old keys)
3126
   *
3127
   * @return static <p>(Mutable)</p>
3128
   */
3129 9
  public function uniqueKeepIndex()
3130
  {
3131 9
    // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array
3132 4
3133 4
    // init
3134 5
    $array = $this->array;
3135
3136
    $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...
3137 9
        \array_keys($array),
3138
        function ($resultArray, $key) use ($array) {
3139
          if (!in_array($array[$key], $resultArray, true)) {
3140
            $resultArray[$key] = $array[$key];
3141
          }
3142
3143
          return $resultArray;
3144
        },
3145
        array()
3146
    );
3147
3148 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...
3149
      $this->array = array();
3150
    } else {
3151
      $this->array = (array)$this->array;
3152
    }
3153
3154
    return $this;
3155
  }
3156
3157
  /**
3158
   * alias: for "Arrayy->unique()"
3159
   *
3160
   * @see Arrayy::unique()
3161
   *
3162
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
3163
   */
3164
  public function uniqueNewIndex()
3165
  {
3166
    return $this->unique();
3167
  }
3168
3169
  /**
3170
   * Prepends one or more values to the beginning of array at once.
3171
   *
3172
   * @return static <p>(Mutable) Return this Arrayy object, with prepended elements to the beginning of array.</p>
3173
   */
3174 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...
3175
  {
3176
    if (func_num_args()) {
3177
      $args = \array_merge(array(&$this->array), func_get_args());
3178
      call_user_func_array('array_unshift', $args);
3179
    }
3180
3181
    return $this;
3182
  }
3183
3184
  /**
3185
   * Get all values from a array.
3186
   *
3187
   * @return static <p>(Immutable)</p>
3188
   */
3189
  public function values()
3190
  {
3191
    return static::create(\array_values((array)$this->array));
3192
  }
3193
3194
  /**
3195
   * Apply the given function to every element in the array, discarding the results.
3196
   *
3197
   * @param callable $callable
3198
   * @param bool     $recursive <p>Whether array will be walked recursively or no</p>
3199
   *
3200
   * @return static <p>(Mutable) Return this Arrayy object, with modified elements.</p>
3201
   */
3202
  public function walk($callable, $recursive = false)
3203
  {
3204
    if (true === $recursive) {
3205
      \array_walk_recursive($this->array, $callable);
3206
    } else {
3207
      \array_walk($this->array, $callable);
3208
    }
3209
3210
    return $this;
3211
  }
3212
}
3213