Completed
Push — master ( 85758d...bcfd97 )
by Lars
02:33
created

Arrayy::average()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 14
ccs 8
cts 8
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
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
   */
40 775
  public function __construct($array = array(), $iteratorClass = '\\Arrayy\\ArrayyIterator')
41
  {
42 775
    $array = $this->fallbackForArray($array);
43 773
    $this->array = $array;
44
45 773
    $this->setIteratorClass($iteratorClass);
46 773
  }
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
   */
55 2
  public function &__get($key)
56
  {
57 2
    $return = $this->get($key);
58
59 2
    if (is_array($return)) {
60
      return static::create($return);
61
    }
62
63 2
    return $return;
64
  }
65
66
  /**
67
   * Call object as function.
68
   *
69
   * @param mixed $key
70
   *
71
   * @return mixed
72
   */
73 1
  public function __invoke($key = null)
74
  {
75 1
    if ($key !== null) {
76 1
      if (isset($this->array[$key])) {
77 1
        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
   */
104 2
  public function __set($key, $value)
105
  {
106 2
    $this->internalSet($key, $value);
107 2
  }
108
109
  /**
110
   * magic to string
111
   *
112
   * @return string
113
   */
114 16
  public function __toString()
115
  {
116 16
    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
   */
138 1
  public function add($value)
139
  {
140 1
    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
   */
150 9
  public function append($value)
151
  {
152 9
    $this->array[] = $value;
153
154 9
    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
   */
168 4
  public function asort($sort_flags = null)
169
  {
170 4
    asort($this->array, $sort_flags);
171
172 4
    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
   */
184 93
  public function count()
185
  {
186 93
    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
   *                (Immutable)
196
   *                An associative Arrayy-object of values from input as
197
   *                keys and their count as value.
198
   *                </p>
199
   */
200 1
  public function countValues()
201
  {
202 1
    return new static(\array_count_values($this->array));
203
  }
204
205
  /**
206
   * Exchange the array for another one.
207
   *
208
   * @param array|Arrayy $data
209
   *
210
   * @return array
211
   */
212 1
  public function exchangeArray($data)
213
  {
214 1
    $this->array = $this->fallbackForArray($data);
215
216 1
    return $this->array;
217
  }
218
219
  /**
220
   * Creates a copy of the ArrayyObject.
221
   *
222
   * @return array
223
   */
224 1
  public function getArrayCopy()
225
  {
226 1
    return $this->array;
227
  }
228
229
  /**
230
   * Returns a new ArrayyIterator, thus implementing the IteratorAggregate interface.
231
   *
232
   * @return ArrayyIterator <p>An iterator for the values in the array.</p>
233
   */
234 20
  public function getIterator()
235
  {
236 20
    $iterator = $this->getIteratorClass();
237
238 20
    return new $iterator($this->array);
239
  }
240
241
  /**
242
   * Gets the iterator classname for the ArrayObject.
243
   *
244
   * @return string
245
   */
246 20
  public function getIteratorClass()
247
  {
248 20
    return $this->iteratorClass;
249
  }
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 4
  public function ksort($sort_flags = null)
263
  {
264 4
    ksort($this->array, $sort_flags);
265
266 4
    return $this;
267
  }
268
269
  /**
270
   * Sort an array using a case insensitive "natural order" algorithm
271
   *
272
   * @return static <p>(Mutable) Return this Arrayy object.</p>
273
   */
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
   *
284
   * @return static <p>(Mutable) Return this Arrayy object.</p>
285
   */
286 1
  public function natsort()
287
  {
288 1
    natsort($this->array);
289
290 1
    return $this;
291
  }
292
293
  /**
294
   * Whether or not an offset exists.
295
   *
296
   * @param int|float|string $offset
297
   *
298
   * @return bool
299
   */
300 40
  public function offsetExists($offset)
301
  {
302 40
    if ($this->isEmpty()) {
303 4
      return false;
304
    }
305
306
    // php cast "bool"-index into "int"-index
307 36
    if ((bool)$offset === $offset) {
308 1
      $offset = (int)$offset;
309 1
    }
310
311 36
    $tmpReturn = \array_key_exists($offset, $this->array);
312
313
    if (
314
        $tmpReturn === true
315 36
        ||
316
        (
317
            $tmpReturn === false
318 12
            &&
319 12
            strpos((string)$offset, $this->pathSeparator) === false
320 12
        )
321 36
    ) {
322 34
      return $tmpReturn;
323
    }
324
325 3
    $offsetExists = false;
326
327 3
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
328
329 3
      $offsetExists = false;
330 3
      $explodedPath = explode($this->pathSeparator, (string)$offset);
331 3
      $lastOffset = \array_pop($explodedPath);
332 3
      $containerPath = implode($this->pathSeparator, $explodedPath);
333
334 3
      $this->callAtPath(
335 3
          $containerPath,
336
          function ($container) use ($lastOffset, &$offsetExists) {
337 3
            $offsetExists = \array_key_exists($lastOffset, $container);
338 3
          }
339 3
      );
340 3
    }
341
342 3
    return $offsetExists;
343
  }
344
345
  /**
346
   * Returns the value at specified offset.
347
   *
348
   * @param mixed $offset
349
   *
350
   * @return mixed <p>Will return null if the offset did not exists.</p>
351
   */
352 26
  public function offsetGet($offset)
353
  {
354 26
    return $this->offsetExists($offset) ? $this->get($offset) : null;
355
  }
356
357
  /**
358
   * Assigns a value to the specified offset.
359
   *
360
   * @param mixed $offset
361
   * @param mixed $value
362
   */
363 17
  public function offsetSet($offset, $value)
364
  {
365 17
    if ($offset === null) {
366 4
      $this->array[] = $value;
367 4
    } else {
368 13
      $this->internalSet($offset, $value);
369
    }
370 17
  }
371
372
  /**
373
   * Unset an offset.
374
   *
375
   * @param mixed $offset
376
   */
377 7
  public function offsetUnset($offset)
378
  {
379 7
    if ($this->isEmpty()) {
380 1
      return;
381
    }
382
383 6
    if (\array_key_exists($offset, $this->array)) {
384 4
      unset($this->array[$offset]);
385
386 4
      return;
387
    }
388
389 3
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
390
391 2
      $path = explode($this->pathSeparator, (string)$offset);
392 2
      $pathToUnset = \array_pop($path);
393
394 2
      $this->callAtPath(
395 2
          implode($this->pathSeparator, $path),
396
          function (&$offset) use ($pathToUnset) {
397 2
            unset($offset[$pathToUnset]);
398 2
          }
399 2
      );
400
401 2
    }
402 3
  }
403
404
  /**
405
   * Serialize the current "Arrayy"-object.
406
   *
407
   * @return string
408
   */
409 1
  public function serialize()
410
  {
411 1
    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 773
  public function setIteratorClass($class)
424
  {
425 773
    if (class_exists($class)) {
426 773
      $this->iteratorClass = $class;
427
428 773
      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
      );
458
    }
459
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
   *
470
   * @return static <p>(Mutable) Return this Arrayy object.</p>
471
   *
472
   * @throws \InvalidArgumentException
473
   */
474 5
  public function uksort($function)
475
  {
476 5
    return $this->customSortKeys($function);
477
  }
478
479
  /**
480
   * Unserialize an string and return this object.
481
   *
482
   * @param string $string
483
   *
484
   * @return static <p>(Mutable)</p>
485
   */
486 1
  public function unserialize($string)
487
  {
488 1
    parent::unserialize($string);
489
490 1
    return $this;
491
  }
492
493
  /**
494
   * Sort an array in reverse order and maintain index association.
495
   *
496
   * @return static <p>(Mutable) Return this Arrayy object.</p>
497
   */
498 4
  public function arsort()
499
  {
500 4
    arsort($this->array);
501
502 4
    return $this;
503
  }
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 2 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
  {
514 2
    $array = $this->array;
515
516 2
    foreach ($array as $key => $value) {
517 2
      $closure($value, $key);
518 2
    }
519
520 2
    return static::create($array);
521
  }
522
523
  /**
524
   * Returns the average value of the current array.
525
   *
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 10
  public function average($decimals = 0)
531
  {
532 10
    $count = $this->count();
533
534 10
    if (!$count) {
535 2
      return 0;
536
    }
537
538 8
    if (!is_int($decimals)) {
539 3
      $decimals = 0;
540 3
    }
541
542 8
    return round(\array_sum($this->array) / $count, $decimals);
543
  }
544
545
  /**
546
   * @param mixed      $path
547
   * @param callable   $callable
548
   * @param null|array $currentOffset
549
   */
550 4
  protected function callAtPath($path, $callable, &$currentOffset = null)
551
  {
552 4
    if ($currentOffset === null) {
553 4
      $currentOffset = &$this->array;
554 4
    }
555
556 4
    $explodedPath = explode($this->pathSeparator, $path);
557 4
    $nextPath = \array_shift($explodedPath);
558
559 4
    if (!isset($currentOffset[$nextPath])) {
560
      return;
561
    }
562
563 4
    if (!empty($explodedPath)) {
564 1
      $this->callAtPath(
565 1
          implode($this->pathSeparator, $explodedPath),
566 1
          $callable,
567 1
          $currentOffset[$nextPath]
568 1
      );
569 1
    } else {
570 4
      $callable($currentOffset[$nextPath]);
571
    }
572 4
  }
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
   *
580
   * @return static <p>(Immutable)</p>
581
   */
582 1
  public function changeKeyCase($case = CASE_LOWER)
583
  {
584 1
    return static::create(UTF8::array_change_key_case($this->array, $case));
0 ignored issues
show
Security Bug introduced by
It seems like \voku\helper\UTF8::array...se($this->array, $case) targeting voku\helper\UTF8::array_change_key_case() can also be of type false; however, Arrayy\Arrayy::create() does only seem to accept array, did you maybe forget to handle an error condition?
Loading history...
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
   * @return static <p>Mutable</p>
595
   */
596 1
  public function changeSeparator($separator)
597
  {
598 1
    $this->pathSeparator = $separator;
599
600 1
    return $this;
601
  }
602
603
  /**
604
   * Create a chunked version of the current array.
605
   *
606
   * @param int  $size         <p>Size of each chunk.</p>
607
   * @param bool $preserveKeys <p>Whether array keys are preserved or no.</p>
608
   *
609
   * @return static <p>(Immutable) A new array of chunks from the original array.</p>
610
   */
611 4
  public function chunk($size, $preserveKeys = false)
612
  {
613 4
    $result = \array_chunk($this->array, $size, $preserveKeys);
614
615 4
    return static::create($result);
616
  }
617
618
  /**
619
   * Clean all falsy values from the current array.
620
   *
621
   * @return static <p>(Immutable)</p>
622
   */
623 8
  public function clean()
624
  {
625 8
    return $this->filter(
626
        function ($value) {
627 7
          return (bool)$value;
628
        }
629 8
    );
630
  }
631
632
  /**
633
   * WARNING!!! -> Clear the current array.
634
   *
635
   * @return static <p>(Mutable) Return this Arrayy object, with an empty array.</p>
636
   */
637 4
  public function clear()
638
  {
639 4
    $this->array = array();
640
641 4
    return $this;
642
  }
643
644
  /**
645
   * Check if an item is in the current array.
646
   *
647
   * @param string|int|float $value
648
   *
649
   * @return bool
650
   */
651 13
  public function contains($value)
652
  {
653 13
    return in_array($value, $this->array, true);
654
  }
655
656
  /**
657
   * Check if an (case-insensitive) string is in the current array.
658
   *
659
   * @param string $value
660
   *
661
   * @return bool
662
   */
663 13
  public function containsCaseInsensitive($value)
664
  {
665 13
    return in_array(
666 13
        UTF8::strtolower($value),
667 13
        \array_map(
668
            array(
669 13
                new UTF8(),
670 13
                'strtolower',
671 13
            ),
672 13
            $this->array
673 13
        ),
674
        true
675 13
    );
676
  }
677
678
  /**
679
   * Check if the given key/index exists in the array.
680
   *
681
   * @param string|int|float $key <p>key/index to search for</p>
682
   *
683
   * @return bool <p>Returns true if the given key/index exists in the array, false otherwise.</p>
684
   */
685 4
  public function containsKey($key)
686
  {
687 4
    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
   *
695
   * @return bool <p>Returns true if the given keys/indexes exists in the array, false otherwise.</p>
696
   */
697 1
  public function containsKeys(array $needles)
698
  {
699 1
    return count(\array_intersect($needles, $this->keys()->getArray())) === count($needles);
700
  }
701
702
  /**
703
   * alias: for "Arrayy->contains()"
704
   *
705
   * @see Arrayy::contains()
706
   *
707
   * @param string|int|float $value
708
   *
709
   * @return bool
710
   */
711 9
  public function containsValue($value)
712
  {
713 9
    return $this->contains($value);
714
  }
715
716
  /**
717
   * Check if all given needles are present in the array.
718
   *
719
   * @param array $needles
720
   *
721
   * @return bool <p>Returns true if the given values exists in the array, false otherwise.</p>
722
   */
723 1
  public function containsValues(array $needles)
724
  {
725 1
    return count(\array_intersect($needles, $this->array)) === count($needles);
726
  }
727
728
  /**
729
   * Creates an Arrayy object.
730
   *
731
   * @param array $array
732
   *
733
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
734
   */
735 481
  public static function create($array = array())
736
  {
737 481
    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
   */
747 1
  public function createByReference(&$array = array())
748
  {
749 1
    $array = $this->fallbackForArray($array);
750
751 1
    $this->array = &$array;
752
753 1
    return $this;
754
  }
755
756
  /**
757
   * Create an new Arrayy object via JSON.
758
   *
759
   * @param string $json
760
   *
761
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
762
   */
763 5
  public static function createFromJson($json)
764
  {
765 5
    $array = UTF8::json_decode($json, true);
766
767 5
    return static::create($array);
768
  }
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 4
  public static function createFromObject(\ArrayAccess $object)
778
  {
779 4
    $array = new static();
780 4
    foreach ($object as $key => $value) {
781
      /** @noinspection OffsetOperationsInspection */
782 3
      $array[$key] = $value;
783 4
    }
784
785 4
    return $array;
786
  }
787
788
  /**
789
   * Create an new instance filled with values from an object.
790
   *
791
   * @param object $object
792
   *
793
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
794
   */
795 5
  public static function createFromObjectVars($object)
796
  {
797 5
    return new static(self::objectToArray($object));
798
  }
799
800
  /**
801
   * Convert a object into an array.
802
   *
803
   * @param object $object
804
   *
805
   * @return mixed
806
   */
807 5
  protected static function objectToArray($object)
808
  {
809 5
    if (!is_object($object)) {
810 4
      return $object;
811
    }
812
813 5
    if (is_object($object)) {
814 5
      $object = get_object_vars($object);
815 5
    }
816 5
    return array_map(array('self', 'objectToArray'), $object);
817
  }
818
819
  /**
820
   * Create an new Arrayy object via string.
821
   *
822
   * @param string      $str       <p>The input string.</p>
823
   * @param string|null $delimiter <p>The boundary string.</p>
824
   * @param string|null $regEx     <p>Use the $delimiter or the $regEx, so if $pattern is null, $delimiter will be
825
   *                               used.</p>
826
   *
827
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
828
   */
829 8
  public static function createFromString($str, $delimiter, $regEx = null)
830
  {
831 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...
832 1
      preg_match_all($regEx, $str, $array);
833
834 1
      if (!empty($array)) {
835 1
        $array = $array[0];
836 1
      }
837
838 1
    } else {
839 7
      $array = explode($delimiter, $str);
840
    }
841
842
    // trim all string in the array
843 8
    \array_walk(
844
        $array,
845
        function (&$val) {
846
          /** @noinspection ReferenceMismatchInspection */
847 8
          if (is_string($val)) {
848 8
            $val = trim($val);
849 8
          }
850 8
        }
851 8
    );
852
853 8
    return static::create($array);
854
  }
855
856
  /**
857
   * Create an new instance containing a range of elements.
858
   *
859
   * @param mixed $low  <p>First value of the sequence.</p>
860
   * @param mixed $high <p>The sequence is ended upon reaching the end value.</p>
861
   * @param int   $step <p>Used as the increment between elements in the sequence.</p>
862
   *
863
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
864
   */
865 1
  public static function createWithRange($low, $high, $step = 1)
866
  {
867 1
    return static::create(range($low, $high, $step));
868
  }
869
870
  /**
871
   * Custom sort by index via "uksort".
872
   *
873
   * @link http://php.net/manual/en/function.uksort.php
874
   *
875
   * @param callable $function
876
   *
877
   * @return static <p>(Mutable) Return this Arrayy object.</p>
878
   *
879
   * @throws \InvalidArgumentException
880
   */
881 5 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...
882
  {
883 5
    if (!is_callable($function)) {
884
      throw new \InvalidArgumentException(
885
          'Passed function must be callable'
886
      );
887
    }
888
889 5
    uksort($this->array, $function);
890
891 5
    return $this;
892
  }
893
894
  /**
895
   * Custom sort by value via "usort".
896
   *
897
   * @link http://php.net/manual/en/function.usort.php
898
   *
899
   * @param callable $function
900
   *
901
   * @return static <p>(Mutable) Return this Arrayy object.</p>
902
   *
903
   * @throws \InvalidArgumentException
904
   */
905 5 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...
906
  {
907 5
    if (!is_callable($function)) {
908
      throw new \InvalidArgumentException(
909
          'Passed function must be callable'
910
      );
911
    }
912
913 5
    usort($this->array, $function);
914
915 5
    return $this;
916
  }
917
918
  /**
919
   * Return values that are only in the current array.
920
   *
921
   * @param array $array
922
   *
923
   * @return static <p>(Immutable)</p>
924
   */
925 12
  public function diff(array $array = array())
926
  {
927 12
    $result = \array_diff($this->array, $array);
928
929 12
    return static::create($result);
930
  }
931
932
  /**
933
   * Return values that are only in the current multi-dimensional array.
934
   *
935
   * @param array      $array
936
   * @param null|array $helperVariableForRecursion <p>(only for internal usage)</p>
937
   *
938
   * @return static <p>(Immutable)</p>
939
   */
940 1
  public function diffRecursive(array $array = array(), $helperVariableForRecursion = null)
941
  {
942 1
    $result = array();
943
944
    if (
945
        $helperVariableForRecursion !== null
946 1
        &&
947 1
        is_array($helperVariableForRecursion)
948 1
    ) {
949 1
      $arrayForTheLoop = $helperVariableForRecursion;
950 1
    } else {
951 1
      $arrayForTheLoop = $this->array;
952
    }
953
954 1
    foreach ($arrayForTheLoop as $key => $value) {
955 1
      if (\array_key_exists($key, $array)) {
956 1
        if (is_array($value)) {
957 1
          $recursiveDiff = $this->diffRecursive($array[$key], $value);
958 1
          if (!empty($recursiveDiff)) {
959 1
            $result[$key] = $recursiveDiff;
960 1
          }
961 1
        } else {
962 1
          if ($value != $array[$key]) {
963 1
            $result[$key] = $value;
964 1
          }
965
        }
966 1
      } else {
967 1
        $result[$key] = $value;
968
      }
969 1
    }
970
971 1
    return static::create($result);
972
  }
973
974
  /**
975
   * Return values that are only in the new $array.
976
   *
977
   * @param array $array
978
   *
979
   * @return static <p>(Immutable)</p>
980
   */
981 8
  public function diffReverse(array $array = array())
982
  {
983 8
    $result = \array_diff($array, $this->array);
984
985 8
    return static::create($result);
986
  }
987
988
  /**
989
   * Divide an array into two arrays. One with keys and the other with values.
990
   *
991
   * @return static <p>(Immutable)</p>
992
   */
993 1
  public function divide()
994
  {
995 1
    return static::create(
996
        array(
997 1
            $this->keys(),
998 1
            $this->values(),
999
        )
1000 1
    );
1001
  }
1002
1003
  /**
1004
   * Iterate over the current array and modify the array's value.
1005
   *
1006
   * @param \Closure $closure
1007
   *
1008
   * @return static <p>(Immutable)</p>
1009
   */
1010 4 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...
1011
  {
1012 4
    $array = $this->array;
1013
1014 4
    foreach ($array as $key => $value) {
1015 4
      $array[$key] = $closure($value, $key);
1016 4
    }
1017
1018 4
    return static::create($array);
1019
  }
1020
1021
  /**
1022
   * Check if a value is in the current array using a closure.
1023
   *
1024
   * @param \Closure $closure
1025
   *
1026
   * @return bool <p>Returns true if the given value is found, false otherwise.</p>
1027
   */
1028 4
  public function exists(\Closure $closure)
1029
  {
1030 4
    $isExists = false;
1031 4
    foreach ($this->array as $key => $value) {
1032 3
      if ($closure($value, $key)) {
1033 1
        $isExists = true;
1034 1
        break;
1035
      }
1036 4
    }
1037
1038 4
    return $isExists;
1039
  }
1040
1041
  /**
1042
   * create a fallback for array
1043
   *
1044
   * 1. use the current array, if it's a array
1045
   * 2. call "getArray()" on object, if there is a "Arrayy"-object
1046
   * 3. fallback to empty array, if there is nothing
1047
   * 4. call "createFromObject()" on object, if there is a "\ArrayAccess"-object
1048
   * 5. call "__toArray()" on object, if the method exists
1049
   * 6. cast a string or object with "__toString()" into an array
1050
   * 7. throw a "InvalidArgumentException"-Exception
1051
   *
1052
   * @param $array
1053
   *
1054
   * @return array
1055
   *
1056
   * @throws \InvalidArgumentException
1057
   */
1058 775
  protected function fallbackForArray(&$array)
1059
  {
1060 775
    if (is_array($array)) {
1061 772
      return $array;
1062
    }
1063
1064 11
    if ($array instanceof self) {
1065 1
      return $array->getArray();
1066
    }
1067
1068 10
    if (!$array) {
1069 6
      return array();
1070
    }
1071
1072 9
    $isObject = is_object($array);
1073
1074 9
    if ($isObject && $array instanceof \ArrayAccess) {
1075
      /** @noinspection ReferenceMismatchInspection */
1076
      return static::createFromObject($array)->getArray();
1077
    }
1078
1079 9
    if ($isObject && $array instanceof \ArrayObject) {
1080
      return $array->getArrayCopy();
1081
    }
1082
1083 9
    if ($isObject && method_exists($array, '__toArray')) {
1084
      return (array)$array->__toArray();
1085
    }
1086
1087
    /** @noinspection ReferenceMismatchInspection */
1088
    if (
1089 9
        is_string($array)
1090
        ||
1091 2
        ($isObject && method_exists($array, '__toString'))
1092 9
    ) {
1093 7
      return array((string)$array);
1094
    }
1095
1096 2
    throw new \InvalidArgumentException(
1097
        'Passed value should be a array'
1098 2
    );
1099
  }
1100
1101
  /**
1102
   * Find all items in an array that pass the truth test.
1103
   *
1104
   * @param \Closure|null $closure [optional] <p>
1105
   *                               The callback function to use
1106
   *                               </p>
1107
   *                               <p>
1108
   *                               If no callback is supplied, all entries of
1109
   *                               input equal to false (see
1110
   *                               converting to
1111
   *                               boolean) will be removed.
1112
   *                               </p>
1113
   *
1114
   *  * @param int $flag [optional] <p>
1115
   *                               Flag determining what arguments are sent to <i>callback</i>:
1116
   *                               </p><ul>
1117
   *                               <li>
1118
   *                               <b>ARRAY_FILTER_USE_KEY</b> [1] - pass key as the only argument
1119
   *                               to <i>callback</i> instead of the value</span>
1120
   *                               </li>
1121
   *                               <li>
1122
   *                               <b>ARRAY_FILTER_USE_BOTH</b> [2] - pass both value and key as
1123
   *                               arguments to <i>callback</i> instead of the value</span>
1124
   *                               </li>
1125
   *                               </ul>
1126
   *
1127
   * @return static <p>(Immutable)</p>
1128
   */
1129 9
  public function filter($closure = null, $flag = 0)
1130
  {
1131 9
    if (!$closure) {
1132 1
      return $this->clean();
1133
    }
1134
1135 9
    if ($flag === 0) {
1136
1137
      // working for all php-versions
1138
1139 9
      $array = \array_filter($this->array, $closure);
1140
1141 9
    } elseif ($flag !== 0 && defined('HHVM_VERSION') === false && Bootup::is_php('5.6')) {
1142
1143
      // working only with php >= 5.6 and not via HHVM
1144
1145
      $array = \array_filter($this->array, $closure, $flag);
1146
1147
    } else {
1148
1149
      // fallback for old php-versions
1150
1151 1
      $array = $this->array;
1152
1153 1
      if ($flag === 2 /* ARRAY_FILTER_USE_KEY */) {
1154 1
        foreach ($array as $key => $value) {
1155 1
          if (!call_user_func($closure, $key)) {
1156 1
            unset($array[$key]);
1157 1
          }
1158 1
        }
1159 1
      } elseif ($flag === 1 /* ARRAY_FILTER_USE_BOTH */) {
1160 1
        foreach ($array as $key => $value) {
1161 1
          if (!call_user_func($closure, $key, $value)) {
1162 1
            unset($array[$key]);
1163 1
          }
1164 1
        }
1165 1
      }
1166
    }
1167
1168 9
    return static::create($array);
1169
  }
1170
1171
  /**
1172
   * Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property
1173
   * within that.
1174
   *
1175
   * @param string $property
1176
   * @param string $value
1177
   * @param string $comparisonOp
1178
   *                            <p>
1179
   *                            'eq' (equals),<br />
1180
   *                            'gt' (greater),<br />
1181
   *                            'gte' || 'ge' (greater or equals),<br />
1182
   *                            'lt' (less),<br />
1183
   *                            'lte' || 'le' (less or equals),<br />
1184
   *                            'ne' (not equals),<br />
1185
   *                            'contains',<br />
1186
   *                            'notContains',<br />
1187
   *                            'newer' (via strtotime),<br />
1188
   *                            'older' (via strtotime),<br />
1189
   *                            </p>
1190
   *
1191
   * @return static <p>(Immutable)</p>
1192
   */
1193 1
  public function filterBy($property, $value, $comparisonOp = null)
1194
  {
1195 1
    if (!$comparisonOp) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $comparisonOp of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

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

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

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
1196 1
      $comparisonOp = is_array($value) ? 'contains' : 'eq';
1197 1
    }
1198
1199
    $ops = array(
1200
        'eq'          => function ($item, $prop, $value) {
1201 1
          return $item[$prop] === $value;
1202 1
        },
1203
        'gt'          => function ($item, $prop, $value) {
1204
          return $item[$prop] > $value;
1205 1
        },
1206
        'ge'          => function ($item, $prop, $value) {
1207
          return $item[$prop] >= $value;
1208 1
        },
1209
        'gte'         => function ($item, $prop, $value) {
1210
          return $item[$prop] >= $value;
1211 1
        },
1212
        'lt'          => function ($item, $prop, $value) {
1213 1
          return $item[$prop] < $value;
1214 1
        },
1215
        'le'          => function ($item, $prop, $value) {
1216
          return $item[$prop] <= $value;
1217 1
        },
1218
        'lte'         => function ($item, $prop, $value) {
1219
          return $item[$prop] <= $value;
1220 1
        },
1221
        'ne'          => function ($item, $prop, $value) {
1222
          return $item[$prop] !== $value;
1223 1
        },
1224
        'contains'    => function ($item, $prop, $value) {
1225 1
          return in_array($item[$prop], (array)$value, true);
1226 1
        },
1227
        'notContains' => function ($item, $prop, $value) {
1228
          return !in_array($item[$prop], (array)$value, true);
1229 1
        },
1230
        'newer'       => function ($item, $prop, $value) {
1231
          return strtotime($item[$prop]) > strtotime($value);
1232 1
        },
1233
        'older'       => function ($item, $prop, $value) {
1234
          return strtotime($item[$prop]) < strtotime($value);
1235 1
        },
1236 1
    );
1237
1238 1
    $result = \array_values(
1239 1
        \array_filter(
1240 1
            (array)$this->array,
1241
            function ($item) use (
1242 1
                $property,
1243 1
                $value,
1244 1
                $ops,
1245 1
                $comparisonOp
1246
            ) {
1247 1
              $item = (array)$item;
1248 1
              $itemArrayy = new Arrayy($item);
1249 1
              $item[$property] = $itemArrayy->get($property, array());
1250
1251 1
              return $ops[$comparisonOp]($item, $property, $value);
1252
            }
1253 1
        )
1254 1
    );
1255
1256 1
    return static::create($result);
1257
  }
1258
1259
  /**
1260
   * Find the first item in an array that passes the truth test,
1261
   *  otherwise return false
1262
   *
1263
   * @param \Closure $closure
1264
   *
1265
   * @return mixed|false <p>Return false if we did not find the value.</p>
1266
   */
1267 8
  public function find(\Closure $closure)
1268
  {
1269 8
    foreach ($this->array as $key => $value) {
1270 6
      if ($closure($value, $key)) {
1271 5
        return $value;
1272
      }
1273 5
    }
1274
1275 3
    return false;
1276
  }
1277
1278
  /**
1279
   * find by ...
1280
   *
1281
   * @param string $property
1282
   * @param string $value
1283
   * @param string $comparisonOp
1284
   *
1285
   * @return static <p>(Immutable)</p>
1286
   */
1287
  public function findBy($property, $value, $comparisonOp = 'eq')
1288
  {
1289
    return $this->filterBy($property, $value, $comparisonOp);
1290
  }
1291
1292
  /**
1293
   * Get the first value from the current array.
1294
   *
1295
   * @return mixed <p>Return null if there wasn't a element.</p>
1296
   */
1297 13
  public function first()
1298
  {
1299 13
    $tmpArray = $this->array;
1300 13
    $result = \array_shift($tmpArray);
1301
1302 13
    if ($result === null) {
1303 3
      return null;
1304
    }
1305
1306 10
    return $result;
1307
  }
1308
1309
  /**
1310
   * Get the first value(s) from the current array.
1311
   *
1312
   * @param int|null $number <p>How many values you will take?</p>
1313
   *
1314
   * @return static <p>(Immutable)</p>
1315
   */
1316 28
  public function firstsImmutable($number = null)
1317
  {
1318 28
    if ($number === null) {
1319 7
      $arrayTmp = $this->array;
1320 7
      $array = (array)\array_shift($arrayTmp);
1321 7
    } else {
1322 21
      $number = (int)$number;
1323 21
      $arrayTmp = $this->array;
1324 21
      $array = \array_splice($arrayTmp, 0, $number, true);
1325
    }
1326
1327 28
    return static::create($array);
1328
  }
1329
1330
  /**
1331
   * Get the first value(s) from the current array.
1332
   *
1333
   * @param int|null $number <p>How many values you will take?</p>
1334
   *
1335
   * @return static <p>(Mutable)</p>
1336
   */
1337 26
  public function firstsMutable($number = null)
1338
  {
1339 26
    if ($number === null) {
1340 11
      $this->array = (array)\array_shift($this->array);
1341 11
    } else {
1342 15
      $number = (int)$number;
1343 15
      $this->array = \array_splice($this->array, 0, $number, true);
1344
    }
1345
1346 26
    return $this;
1347
  }
1348
1349
  /**
1350
   * Exchanges all keys with their associated values in an array.
1351
   *
1352
   * @return static <p>(Immutable)</p>
1353
   */
1354 1
  public function flip()
1355
  {
1356 1
    $result = \array_flip($this->array);
1357
1358 1
    return static::create($result);
1359
  }
1360
1361
  /**
1362
   * Get a value from an array (optional using dot-notation).
1363
   *
1364
   * @param string $key      <p>The key to look for.</p>
1365
   * @param mixed  $fallback <p>Value to fallback to.</p>
1366
   * @param array  $array    <p>The array to get from, if it's set to "null" we use the current array from the
1367
   *                         class.</p>
1368
   *
1369
   * @return mixed
1370
   */
1371 61
  public function get($key, $fallback = null, $array = null)
1372
  {
1373
    if (
1374
        $array !== null
1375 61
        &&
1376 3
        is_array($array)
1377 61
    ) {
1378 3
      $usedArray = $array;
1379 3
    } else {
1380 59
      $usedArray = $this->array;
1381
    }
1382
1383 61
    if ($key === null) {
1384 1
      return static::create($usedArray);
1385
    }
1386
1387
    // php cast "bool"-index into "int"-index
1388 61
    if ((bool)$key === $key) {
1389 2
      $key = (int)$key;
1390 2
    }
1391
1392 61
    if (\array_key_exists($key, $usedArray) === true) {
1393 51
      if (is_array($usedArray[$key])) {
1394 6
        return static::create($usedArray[$key]);
1395
      }
1396
1397 47
      return $usedArray[$key];
1398
    }
1399
1400
    // Crawl through array, get key according to object or not
1401 20
    foreach (explode($this->pathSeparator, (string)$key) as $segment) {
1402 20
      if (!isset($usedArray[$segment])) {
1403 19
        return $fallback instanceof \Closure ? $fallback() : $fallback;
1404
      }
1405
1406 5
      $usedArray = $usedArray[$segment];
1407 5
    }
1408
1409 5
    if (is_array($usedArray)) {
1410
      return static::create($usedArray);
1411
    }
1412
1413 5
    return $usedArray;
1414
  }
1415
1416
  /**
1417
   * Get the current array from the "Arrayy"-object.
1418
   *
1419
   * @return array
1420
   */
1421 496
  public function getArray()
1422
  {
1423 496
    \array_map(array('self', 'internalGetArray'), $this->array);
1424
1425 496
    return $this->array;
1426
  }
1427
1428
  /**
1429
   * Get the current array from the "Arrayy"-object as object.
1430
   *
1431
   * @return \stdClass (object)
1432
   */
1433 4
  public function getObject()
1434
  {
1435 4
    return self::arrayToObject($this->getArray());
1436
  }
1437
1438
  /**
1439
   * Convert an array into a object.
1440
   *
1441
   * @param array $array PHP array
1442
   *
1443
   * @return \stdClass (object)
1444
   */
1445 4
  protected static function arrayToObject(array $array = array())
1446
  {
1447 4
    $object = new \stdClass();
1448
1449 4
    if (!is_array($array) || count($array) < 1) {
1450 1
      return $object;
1451
    }
1452
1453 3
    foreach ($array as $name => $value) {
1454 3
      if (is_array($value)) {
1455 1
        $object->$name = self::arrayToObject($value);
1456 1
        continue;
1457
      }
1458 3
      $object->{$name} = $value;
1459 3
    }
1460
1461 3
    return $object;
1462
  }
1463
1464
  /**
1465
   * Returns the values from a single column of the input array, identified by
1466
   * the $columnKey, can be used to extract data-columns from multi-arrays.
1467
   *
1468
   * Info: Optionally, you may provide an $indexKey to index the values in the returned
1469
   * array by the values from the $indexKey column in the input array.
1470
   *
1471
   * @param mixed $columnKey
1472
   * @param mixed $indexKey
1473
   *
1474
   * @return static <p>(Immutable)</p>
1475
   */
1476 1
  public function getColumn($columnKey = null, $indexKey = null)
1477
  {
1478 1
    $result = \array_column($this->array, $columnKey, $indexKey);
1479
1480 1
    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 1478 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...
1481
  }
1482
1483
  /**
1484
   * Get correct PHP constant for direction.
1485
   *
1486
   * @param int|string $direction
1487
   *
1488
   * @return int
1489
   */
1490 38
  protected function getDirection($direction)
1491
  {
1492 38
    if (is_string($direction)) {
1493 10
      $direction = strtolower($direction);
1494
1495 10
      if ($direction === 'desc') {
1496 2
        $direction = SORT_DESC;
1497 2
      } else {
1498 8
        $direction = SORT_ASC;
1499
      }
1500 10
    }
1501
1502
    if (
1503
        $direction !== SORT_DESC
1504 38
        &&
1505
        $direction !== SORT_ASC
1506 38
    ) {
1507
      $direction = SORT_ASC;
1508
    }
1509
1510 38
    return $direction;
1511
  }
1512
1513
  /**
1514
   * alias: for "Arrayy->keys()"
1515
   *
1516
   * @see Arrayy::keys()
1517
   *
1518
   * @return static <p>(Immutable)</p>
1519
   */
1520 1
  public function getKeys()
1521
  {
1522 1
    return $this->keys();
1523
  }
1524
1525
  /**
1526
   * alias: for "Arrayy->randomImmutable()"
1527
   *
1528
   * @see Arrayy::randomImmutable()
1529
   *
1530
   * @return static <p>(Immutable)</p>
1531
   */
1532 3
  public function getRandom()
1533
  {
1534 3
    return $this->randomImmutable();
1535
  }
1536
1537
  /**
1538
   * alias: for "Arrayy->randomKey()"
1539
   *
1540
   * @see Arrayy::randomKey()
1541
   *
1542
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
1543
   */
1544 3
  public function getRandomKey()
1545
  {
1546 3
    return $this->randomKey();
1547
  }
1548
1549
  /**
1550
   * alias: for "Arrayy->randomKeys()"
1551
   *
1552
   * @see Arrayy::randomKeys()
1553
   *
1554
   * @param int $number
1555
   *
1556
   * @return static <p>(Immutable)</p>
1557
   */
1558 9
  public function getRandomKeys($number)
1559
  {
1560 9
    return $this->randomKeys($number);
1561
  }
1562
1563
  /**
1564
   * alias: for "Arrayy->randomValue()"
1565
   *
1566
   * @see Arrayy::randomValue()
1567
   *
1568
   * @return mixed <p>get a random value or null if there wasn't a value.</p>
1569
   */
1570 3
  public function getRandomValue()
1571
  {
1572 3
    return $this->randomValue();
1573
  }
1574
1575
  /**
1576
   * alias: for "Arrayy->randomValues()"
1577
   *
1578
   * @see Arrayy::randomValues()
1579
   *
1580
   * @param int $number
1581
   *
1582
   * @return static <p>(Immutable)</p>
1583
   */
1584 6
  public function getRandomValues($number)
1585
  {
1586 6
    return $this->randomValues($number);
1587
  }
1588
1589
  /**
1590
   * Group values from a array according to the results of a closure.
1591
   *
1592
   * @param string $grouper <p>A callable function name.</p>
1593
   * @param bool   $saveKeys
1594
   *
1595
   * @return static <p>(Immutable)</p>
1596
   */
1597 3
  public function group($grouper, $saveKeys = false)
1598
  {
1599 3
    $array = (array)$this->array;
1600 3
    $result = array();
1601
1602
    // Iterate over values, group by property/results from closure
1603 3
    foreach ($array as $key => $value) {
1604
1605 3
      $groupKey = is_callable($grouper) ? $grouper($value, $key) : $this->get($grouper, null, $value);
1606 3
      $newValue = $this->get($groupKey, null, $result);
1607
1608 3
      if ($groupKey instanceof self) {
1609
        $groupKey = $groupKey->getArray();
1610
      }
1611
1612 3
      if ($newValue instanceof self) {
1613 3
        $newValue = $newValue->getArray();
1614 3
      }
1615
1616
      // Add to results
1617 3
      if ($groupKey !== null) {
1618 2
        if ($saveKeys) {
1619 1
          $result[$groupKey] = $newValue;
1620 1
          $result[$groupKey][$key] = $value;
1621 1
        } else {
1622 1
          $result[$groupKey] = $newValue;
1623 1
          $result[$groupKey][] = $value;
1624
        }
1625 2
      }
1626
1627 3
    }
1628
1629 3
    return static::create($result);
1630
  }
1631
1632
  /**
1633
   * Check if an array has a given key.
1634
   *
1635
   * @param mixed $key
1636
   *
1637
   * @return bool
1638
   */
1639 22
  public function has($key)
1640
  {
1641
    // Generate unique string to use as marker.
1642 22
    $unFound = (string)uniqid('arrayy', true);
1643
1644 22
    return $this->get($key, $unFound) !== $unFound;
1645
  }
1646
1647
  /**
1648
   * Implodes an array.
1649
   *
1650
   * @param string $glue
1651
   *
1652
   * @return string
1653
   */
1654 28
  public function implode($glue = '')
1655
  {
1656 28
    return self::implode_recursive($glue, $this->array);
1657
  }
1658
1659
  /**
1660
   * @param string $glue
1661
   * @param string|array $pieces
1662
   *
1663
   * @return string
1664
   */
1665 28
  protected static function implode_recursive($glue = '', $pieces) {
1666 28
    if (is_array($pieces)) {
1667 28
      $pieces_count = count($pieces);
1668
1669 28
      return implode(
1670 28
          $glue,
1671 28
          array_map(
1672 28
              array('self', 'implode_recursive'),
1673 28
              array_fill(0, ($pieces_count > 0 ? $pieces_count : 1), $glue),
1674
              $pieces
1675 28
          )
1676 28
      );
1677
    }
1678
1679 28
    return $pieces;
1680
  }
1681
1682
  /**
1683
   * Given a list and an iterate-function that returns
1684
   * a key for each element in the list (or a property name),
1685
   * returns an object with an index of each item.
1686
   *
1687
   * Just like groupBy, but for when you know your keys are unique.
1688
   *
1689
   * @param mixed $key
1690
   *
1691
   * @return static <p>(Immutable)</p>
1692
   */
1693 3
  public function indexBy($key)
1694
  {
1695 3
    $results = array();
1696
1697 3
    foreach ($this->array as $a) {
1698 3
      if (\array_key_exists($key, $a) === true) {
1699 2
        $results[$a[$key]] = $a;
1700 2
      }
1701 3
    }
1702
1703 3
    return static::create($results);
1704
  }
1705
1706
  /**
1707
   * alias: for "Arrayy->searchIndex()"
1708
   *
1709
   * @see Arrayy::searchIndex()
1710
   *
1711
   * @param mixed $value <p>The value to search for.</p>
1712
   *
1713
   * @return mixed
1714
   */
1715 4
  public function indexOf($value)
1716
  {
1717 4
    return $this->searchIndex($value);
1718
  }
1719
1720
  /**
1721
   * Get everything but the last..$to items.
1722
   *
1723
   * @param int $to
1724
   *
1725
   * @return static <p>(Immutable)</p>
1726
   */
1727 12
  public function initial($to = 1)
1728
  {
1729 12
    $slice = count($this->array) - $to;
1730
1731 12
    return $this->firstsImmutable($slice);
1732
  }
1733
1734
  /**
1735
   * @param mixed $value
1736
   */
1737 410
  protected function internalGetArray(&$value)
1738
  {
1739 410
    if ($value instanceof self) {
1740
1741
      $valueTmp = $value->getArray();
1742
      if (count($valueTmp) === 0) {
1743
        $value = array();
1744
      } else {
1745
        /** @noinspection PhpUnusedLocalVariableInspection */
1746
        $value = &$valueTmp;
1747
      }
1748
1749 410
    } 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...
1750
      /** @noinspection PhpUnusedLocalVariableInspection */
1751
      $value = &$value->jsonSerialize();
1752
    }
1753 410
  }
1754
1755
  /**
1756
   * Internal mechanics of remove method.
1757
   *
1758
   * @param string $key
1759
   *
1760
   * @return boolean
1761
   */
1762 18
  protected function internalRemove($key)
1763
  {
1764 18
    $path = explode($this->pathSeparator, (string)$key);
1765
1766
    // Crawl though the keys
1767 18
    while (count($path) > 1) {
1768
      $key = \array_shift($path);
1769
1770
      if (!$this->has($key)) {
1771
        return false;
1772
      }
1773
1774
      $this->array = &$this->array[$key];
1775
    }
1776
1777 18
    $key = \array_shift($path);
1778
1779 18
    unset($this->array[$key]);
1780
1781 18
    return true;
1782
  }
1783
1784
  /**
1785
   * Internal mechanic of set method.
1786
   *
1787
   * @param string $key
1788
   * @param mixed  $value
1789
   *
1790
   * @return bool
1791
   */
1792 30
  protected function internalSet($key, $value)
1793
  {
1794 30
    if ($key === null) {
1795
      return false;
1796
    }
1797
1798
    // init
1799 30
    $array =& $this->array;
1800 30
    $path = explode($this->pathSeparator, (string)$key);
1801
1802
    // Crawl through the keys
1803 30
    while (count($path) > 1) {
1804 3
      $key = \array_shift($path);
1805
1806
      // If the key doesn't exist at this depth, we will just create an empty array
1807
      // to hold the next value, allowing us to create the arrays to hold final
1808
      // values at the correct depth. Then we'll keep digging into the array.
1809 3
      if (!isset($array[$key]) || !is_array($array[$key])) {
1810
        $array[$key] = static::create(array());
1811
      }
1812
1813 3
      $array =& $array[$key];
1814 3
    }
1815
1816 30
    $array[\array_shift($path)] = $value;
1817
1818 30
    return true;
1819
  }
1820
1821
  /**
1822
   * Return an array with all elements found in input array.
1823
   *
1824
   * @param array $search
1825
   *
1826
   * @return static <p>(Immutable)</p>
1827
   */
1828 2
  public function intersection(array $search)
1829
  {
1830 2
    return static::create(\array_values(\array_intersect($this->array, $search)));
1831
  }
1832
1833
  /**
1834
   * Return a boolean flag which indicates whether the two input arrays have any common elements.
1835
   *
1836
   * @param array $search
1837
   *
1838
   * @return bool
1839
   */
1840 1
  public function intersects(array $search)
1841
  {
1842 1
    return count($this->intersection($search)->array) > 0;
1843
  }
1844
1845
  /**
1846
   * Invoke a function on all of an array's values.
1847
   *
1848
   * @param mixed $callable
1849
   * @param mixed $arguments
1850
   *
1851
   * @return static <p>(Immutable)</p>
1852
   */
1853 1
  public function invoke($callable, $arguments = array())
1854
  {
1855
    // If one argument given for each iteration, create an array for it.
1856 1
    if (!is_array($arguments)) {
1857 1
      $arguments = StaticArrayy::repeat($arguments, count($this->array))->getArray();
1858 1
    }
1859
1860
    // If the callable has arguments, pass them.
1861 1
    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...
1862 1
      $array = \array_map($callable, $this->array, $arguments);
1863 1
    } else {
1864 1
      $array = \array_map($callable, $this->array);
1865
    }
1866
1867 1
    return static::create($array);
1868
  }
1869
1870
  /**
1871
   * Check whether array is associative or not.
1872
   *
1873
   * @return bool <p>Returns true if associative, false otherwise.</p>
1874
   */
1875 15
  public function isAssoc()
1876
  {
1877 15
    if ($this->isEmpty()) {
1878 3
      return false;
1879
    }
1880
1881 13
    foreach ($this->keys()->getArray() as $key) {
1882 13
      if (!is_string($key)) {
1883 11
        return false;
1884
      }
1885 3
    }
1886
1887 3
    return true;
1888
  }
1889
1890
  /**
1891
   * Check whether the array is empty or not.
1892
   *
1893
   * @return bool <p>Returns true if empty, false otherwise.</p>
1894
   */
1895 88
  public function isEmpty()
1896
  {
1897 88
    return !$this->array;
1898
  }
1899
1900
  /**
1901
   * Check if the current array is equal to the given "$array" or not.
1902
   *
1903
   * @param array $array
1904
   *
1905
   * @return bool
1906
   */
1907
  public function isEqual(array $array)
1908
  {
1909
    return ($this->array === $array);
1910
  }
1911
1912
  /**
1913
   * Check if the current array is a multi-array.
1914
   *
1915
   * @return bool
1916
   */
1917 14
  public function isMultiArray()
1918
  {
1919 14
    return !(count($this->array) === count($this->array, COUNT_RECURSIVE));
1920
  }
1921
1922
  /**
1923
   * Check whether array is numeric or not.
1924
   *
1925
   * @return bool <p>Returns true if numeric, false otherwise.</p>
1926
   */
1927 5
  public function isNumeric()
1928
  {
1929 5
    if ($this->isEmpty()) {
1930 2
      return false;
1931
    }
1932
1933 4
    foreach ($this->keys() as $key) {
1934 4
      if (!is_int($key)) {
1935 2
        return false;
1936
      }
1937 3
    }
1938
1939 2
    return true;
1940
  }
1941
1942
  /**
1943
   * Check if the current array is sequential [0, 1, 2, 3, 4, 5 ...] or not.
1944
   *
1945
   * @return bool
1946
   */
1947 1
  public function isSequential()
1948
  {
1949 1
    return \array_keys($this->array) === range(0, count($this->array) - 1);
1950
  }
1951
1952
  /**
1953
   * @return array
1954
   */
1955
  public function jsonSerialize()
1956
  {
1957
    return $this->getArray();
1958
  }
1959
1960
  /**
1961
   * Get all keys from the current array.
1962
   *
1963
   * @return static <p>(Immutable)</p>
1964
   */
1965 25
  public function keys()
1966
  {
1967 25
    return static::create(\array_keys($this->array));
1968
  }
1969
1970
  /**
1971
   * Sort an array by key in reverse order.
1972
   *
1973
   * @param int $sort_flags [optional] <p>
1974
   *                        You may modify the behavior of the sort using the optional
1975
   *                        parameter sort_flags, for details
1976
   *                        see sort.
1977
   *                        </p>
1978
   *
1979
   * @return static <p>(Mutable) Return this Arrayy object.</p>
1980
   */
1981 4
  public function krsort($sort_flags = null)
1982
  {
1983 4
    krsort($this->array, $sort_flags);
1984
1985 4
    return $this;
1986
  }
1987
1988
  /**
1989
   * Get the last value from the current array.
1990
   *
1991
   * @return mixed <p>Return null if there wasn't a element.</p>
1992
   */
1993 4
  public function last()
1994
  {
1995 4
    return $this->pop();
1996
  }
1997
1998
  /**
1999
   * Get the last value(s) from the current array.
2000
   *
2001
   * @param int|null $number
2002
   *
2003
   * @return static <p>(Immutable)</p>
2004
   */
2005 13
  public function lastsImmutable($number = null)
2006
  {
2007 13
    if ($this->isEmpty()) {
2008 1
      return static::create();
2009
    }
2010
2011 12
    if ($number === null) {
2012 8
      $poppedValue = $this->pop();
2013
2014 8
      if ($poppedValue === null) {
2015 1
        $poppedValue = array($poppedValue);
2016 1
      } else {
2017 7
        $poppedValue = (array)$poppedValue;
2018
      }
2019
2020 8
      $arrayy = static::create($poppedValue);
2021 8
    } else {
2022 4
      $number = (int)$number;
2023 4
      $arrayy = $this->rest(-$number);
2024
    }
2025
2026 12
    return $arrayy;
2027
  }
2028
2029
  /**
2030
   * Get the last value(s) from the current array.
2031
   *
2032
   * @param int|null $number
2033
   *
2034
   * @return static <p>(Mutable)</p>
2035
   */
2036 13
  public function lastsMutable($number = null)
2037
  {
2038 13
    if ($this->isEmpty()) {
2039 1
      return $this;
2040
    }
2041
2042 12
    if ($number === null) {
2043 8
      $poppedValue = $this->pop();
2044
2045 8
      if ($poppedValue === null) {
2046 1
        $poppedValue = array($poppedValue);
2047 1
      } else {
2048 7
        $poppedValue = (array)$poppedValue;
2049
      }
2050
2051 8
      $this->array = static::create($poppedValue)->array;
2052 8
    } else {
2053 4
      $number = (int)$number;
2054 4
      $this->array = $this->rest(-$number)->array;
2055
    }
2056
2057 12
    return $this;
2058
  }
2059
2060
  /**
2061
   * Count the values from the current array.
2062
   *
2063
   * alias: for "Arrayy->size()"
2064
   *
2065
   * @see Arrayy::size()
2066
   *
2067
   * @return int
2068
   */
2069 10
  public function length()
2070
  {
2071 10
    return $this->size();
2072
  }
2073
2074
  /**
2075
   * Apply the given function to the every element of the array,
2076
   * collecting the results.
2077
   *
2078
   * @param callable $callable
2079
   *
2080
   * @return static <p>(Immutable) Arrayy object with modified elements.</p>
2081
   */
2082 4
  public function map($callable)
2083
  {
2084 4
    $result = \array_map($callable, $this->array);
2085
2086 4
    return static::create($result);
2087
  }
2088
2089
  /**
2090
   * Check if all items in current array match a truth test.
2091
   *
2092
   * @param \Closure $closure
2093
   *
2094
   * @return bool
2095
   */
2096 15 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...
2097
  {
2098 15
    if (count($this->array) === 0) {
2099 2
      return false;
2100
    }
2101
2102
    // init
2103 13
    $array = $this->array;
2104
2105 13
    foreach ($array as $key => $value) {
2106 13
      $value = $closure($value, $key);
2107
2108 13
      if ($value === false) {
2109 7
        return false;
2110
      }
2111 9
    }
2112
2113 7
    return true;
2114
  }
2115
2116
  /**
2117
   * Check if any item in the current array matches a truth test.
2118
   *
2119
   * @param \Closure $closure
2120
   *
2121
   * @return bool
2122
   */
2123 14 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...
2124
  {
2125 14
    if (count($this->array) === 0) {
2126 2
      return false;
2127
    }
2128
2129
    // init
2130 12
    $array = $this->array;
2131
2132 12
    foreach ($array as $key => $value) {
2133 12
      $value = $closure($value, $key);
2134
2135 12
      if ($value === true) {
2136 9
        return true;
2137
      }
2138 5
    }
2139
2140 4
    return false;
2141
  }
2142
2143
  /**
2144
   * Get the max value from an array.
2145
   *
2146
   * @return mixed
2147
   */
2148 10
  public function max()
2149
  {
2150 10
    if ($this->count() === 0) {
2151 1
      return false;
2152
    }
2153
2154 9
    return max($this->array);
2155
  }
2156
2157
  /**
2158
   * Merge the new $array into the current array.
2159
   *
2160
   * - keep key,value from the current array, also if the index is in the new $array
2161
   *
2162
   * @param array $array
2163
   * @param bool  $recursive
2164
   *
2165
   * @return static <p>(Immutable)</p>
2166
   */
2167 25 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...
2168
  {
2169 25
    if (true === $recursive) {
2170 4
      $result = \array_replace_recursive($this->array, $array);
2171 4
    } else {
2172 21
      $result = \array_replace($this->array, $array);
2173
    }
2174
2175 25
    return static::create($result);
2176
  }
2177
2178
  /**
2179
   * Merge the new $array into the current array.
2180
   *
2181
   * - replace duplicate assoc-keys from the current array with the key,values from the new $array
2182
   * - create new indexes
2183
   *
2184
   * @param array $array
2185
   * @param bool  $recursive
2186
   *
2187
   * @return static <p>(Immutable)</p>
2188
   */
2189 16 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...
2190
  {
2191 16
    if (true === $recursive) {
2192 4
      $result = \array_merge_recursive($this->array, $array);
2193 4
    } else {
2194 12
      $result = \array_merge($this->array, $array);
2195
    }
2196
2197 16
    return static::create($result);
2198
  }
2199
2200
  /**
2201
   * Merge the the current array into the $array.
2202
   *
2203
   * - use key,value from the new $array, also if the index is in the current array
2204
   *
2205
   * @param array $array
2206
   * @param bool  $recursive
2207
   *
2208
   * @return static <p>(Immutable)</p>
2209
   */
2210 16 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...
2211
  {
2212 16
    if (true === $recursive) {
2213 4
      $result = \array_replace_recursive($array, $this->array);
2214 4
    } else {
2215 12
      $result = \array_replace($array, $this->array);
2216
    }
2217
2218 16
    return static::create($result);
2219
  }
2220
2221
  /**
2222
   * Merge the current array into the new $array.
2223
   *
2224
   * - replace duplicate assoc-keys from new $array with the key,values from the current array
2225
   * - create new indexes
2226
   *
2227
   * @param array $array
2228
   * @param bool  $recursive
2229
   *
2230
   * @return static <p>(Immutable)</p>
2231
   */
2232 17 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...
2233
  {
2234 17
    if (true === $recursive) {
2235 4
      $result = \array_merge_recursive($array, $this->array);
2236 4
    } else {
2237 13
      $result = \array_merge($array, $this->array);
2238
    }
2239
2240 17
    return static::create($result);
2241
  }
2242
2243
  /**
2244
   * Get the min value from an array.
2245
   *
2246
   * @return mixed
2247
   */
2248 10
  public function min()
2249
  {
2250 10
    if ($this->count() === 0) {
2251 1
      return false;
2252
    }
2253
2254 9
    return min($this->array);
2255
  }
2256
2257
  /**
2258
   * Move an array element to a new index.
2259
   *
2260
   * cherry-picked from: http://stackoverflow.com/questions/12624153/move-an-array-element-to-a-new-index-in-php
2261
   *
2262
   * @param int|string $from
2263
   * @param int|string $to
2264
   *
2265
   * @return static <p>(Immutable)</p>
2266
   */
2267 1
  public function moveElement($from, $to)
2268
  {
2269 1
    $array = $this->array;
2270
2271 1
    if (is_int($from)) {
2272 1
      $tmp = \array_splice($array, $from, 1);
2273 1
      \array_splice($array, $to, 0, $tmp);
2274 1
      $output = $array;
2275 1
    } elseif (is_string($from)) {
2276 1
      $indexToMove = \array_search($from, \array_keys($array), true);
2277 1
      $itemToMove = $array[$from];
2278 1
      \array_splice($array, $indexToMove, 1);
2279 1
      $i = 0;
2280 1
      $output = array();
2281 1
      foreach ($array as $key => $item) {
2282 1
        if ($i == $to) {
2283 1
          $output[$from] = $itemToMove;
2284 1
        }
2285 1
        $output[$key] = $item;
2286 1
        $i++;
2287 1
      }
2288 1
    } else {
2289
      $output = array();
2290
    }
2291
2292 1
    return static::create($output);
2293
  }
2294
2295
  /**
2296
   * Get a subset of the items from the given array.
2297
   *
2298
   * @param mixed[] $keys
2299
   *
2300
   * @return static <p>(Immutable)</p>
2301
   */
2302
  public function only(array $keys)
2303
  {
2304
    $array = $this->array;
2305
2306
    return static::create(\array_intersect_key($array, \array_flip($keys)));
2307
  }
2308
2309
  /**
2310
   * Pad array to the specified size with a given value.
2311
   *
2312
   * @param int   $size  <p>Size of the result array.</p>
2313
   * @param mixed $value <p>Empty value by default.</p>
2314
   *
2315
   * @return static <p>(Immutable) Arrayy object padded to $size with $value.</p>
2316
   */
2317 4
  public function pad($size, $value)
2318
  {
2319 4
    $result = \array_pad($this->array, $size, $value);
2320
2321 4
    return static::create($result);
2322
  }
2323
2324
  /**
2325
   * Pop a specified value off the end of the current array.
2326
   *
2327
   * @return mixed <p>(Mutable) The popped element from the current array.</p>
2328
   */
2329 16
  public function pop()
2330
  {
2331 16
    return \array_pop($this->array);
2332
  }
2333
2334
  /**
2335
   * Prepend a value to the current array.
2336
   *
2337
   * @param mixed $value
2338
   * @param mixed $key
2339
   *
2340
   * @return static <p>(Mutable) Return this Arrayy object, with the prepended value.</p>
2341
   */
2342 8
  public function prepend($value, $key = null)
2343
  {
2344 8
    if ($key === null) {
2345 8
      \array_unshift($this->array, $value);
2346 8
    } else {
2347
      /** @noinspection AdditionOperationOnArraysInspection */
2348 1
      $this->array = array($key => $value) + $this->array;
2349
    }
2350
2351 8
    return $this;
2352
  }
2353
2354
  /**
2355
   * Push one or more values onto the end of array at once.
2356
   *
2357
   * @return static <p>(Mutable) Return this Arrayy object, with pushed elements to the end of array.</p>
2358
   */
2359 4 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...
2360
  {
2361 4
    if (func_num_args()) {
2362 4
      $args = \array_merge(array(&$this->array), func_get_args());
2363 4
      call_user_func_array('array_push', $args);
2364 4
    }
2365
2366 4
    return $this;
2367
  }
2368
2369
  /**
2370
   * Get a random value from the current array.
2371
   *
2372
   * @param null|int $number <p>How many values you will take?</p>
2373
   *
2374
   * @return static <p>(Immutable)</p>
2375
   */
2376 17
  public function randomImmutable($number = null)
2377
  {
2378 17
    if ($this->count() === 0) {
2379
      return static::create();
2380
    }
2381
2382 17 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...
2383 14
      $arrayRandValue = array($this->array[\array_rand($this->array)]);
2384
2385 14
      return static::create($arrayRandValue);
2386
    }
2387
2388 5
    $arrayTmp = $this->array;
2389 5
    shuffle($arrayTmp);
2390
2391 5
    return static::create($arrayTmp)->firstsImmutable($number);
2392
  }
2393
2394
  /**
2395
   * Pick a random key/index from the keys of this array.
2396
   *
2397
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
2398
   *
2399
   * @throws \RangeException If array is empty
2400
   */
2401 4
  public function randomKey()
2402
  {
2403 4
    $result = $this->randomKeys(1);
2404
2405 4
    if (!isset($result[0])) {
2406
      $result[0] = null;
2407
    }
2408
2409 4
    return $result[0];
2410
  }
2411
2412
  /**
2413
   * Pick a given number of random keys/indexes out of this array.
2414
   *
2415
   * @param int $number <p>The number of keys/indexes (should be <= $this->count())</p>
2416
   *
2417
   * @return static <p>(Immutable)</p>
2418
   *
2419
   * @throws \RangeException If array is empty
2420
   */
2421 14
  public function randomKeys($number)
2422
  {
2423 14
    $number = (int)$number;
2424 14
    $count = $this->count();
2425
2426 14
    if ($number === 0 || $number > $count) {
2427 3
      throw new \RangeException(
2428 3
          sprintf(
2429 3
              'Number of requested keys (%s) must be equal or lower than number of elements in this array (%s)',
2430 3
              $number,
2431
              $count
2432 3
          )
2433 3
      );
2434
    }
2435
2436 11
    $result = (array)\array_rand($this->array, $number);
2437
2438 11
    return static::create($result);
2439
  }
2440
2441
  /**
2442
   * Get a random value from the current array.
2443
   *
2444
   * @param null|int $number <p>How many values you will take?</p>
2445
   *
2446
   * @return static <p>(Mutable)</p>
2447
   */
2448 17
  public function randomMutable($number = null)
2449
  {
2450 17
    if ($this->count() === 0) {
2451
      return static::create();
2452
    }
2453
2454 17 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...
2455 7
      $arrayRandValue = array($this->array[\array_rand($this->array)]);
2456 7
      $this->array = $arrayRandValue;
2457
2458 7
      return $this;
2459
    }
2460
2461 11
    shuffle($this->array);
2462
2463 11
    return $this->firstsMutable($number);
2464
  }
2465
2466
  /**
2467
   * Pick a random value from the values of this array.
2468
   *
2469
   * @return mixed <p>Get a random value or null if there wasn't a value.</p>
2470
   */
2471 4
  public function randomValue()
2472
  {
2473 4
    $result = $this->randomImmutable();
2474
2475 4
    if (!isset($result[0])) {
2476
      $result[0] = null;
2477
    }
2478
2479 4
    return $result[0];
2480
  }
2481
2482
  /**
2483
   * Pick a given number of random values out of this array.
2484
   *
2485
   * @param int $number
2486
   *
2487
   * @return static <p>(Mutable)</p>
2488
   */
2489 7
  public function randomValues($number)
2490
  {
2491 7
    $number = (int)$number;
2492
2493 7
    return $this->randomMutable($number);
2494
  }
2495
2496
  /**
2497
   * Get a random value from an array, with the ability to skew the results.
2498
   *
2499
   * Example: randomWeighted(['foo' => 1, 'bar' => 2]) has a 66% chance of returning bar.
2500
   *
2501
   * @param array    $array
2502
   * @param null|int $number <p>How many values you will take?</p>
2503
   *
2504
   * @return static <p>(Immutable)</p>
2505
   */
2506 9
  public function randomWeighted(array $array, $number = null)
2507
  {
2508 9
    $options = array();
2509 9
    foreach ($array as $option => $weight) {
2510 9
      if ($this->searchIndex($option) !== false) {
2511 2
        for ($i = 0; $i < $weight; ++$i) {
2512 1
          $options[] = $option;
2513 1
        }
2514 2
      }
2515 9
    }
2516
2517 9
    return $this->mergeAppendKeepIndex($options)->randomImmutable($number);
2518
  }
2519
2520
  /**
2521
   * Reduce the current array via callable e.g. anonymous-function.
2522
   *
2523
   * @param mixed $callable
2524
   * @param array $init
2525
   *
2526
   * @return static <p>(Immutable)</p>
2527
   */
2528 4
  public function reduce($callable, array $init = array())
2529
  {
2530 4
    $result = \array_reduce($this->array, $callable, $init);
2531
2532 4
    if ($result === null) {
2533
      $this->array = array();
2534
    } else {
2535 4
      $this->array = (array)$result;
2536
    }
2537
2538 4
    return static::create($this->array);
2539
  }
2540
2541
  /**
2542
   * Create a numerically re-indexed Arrayy object.
2543
   *
2544
   * @return static <p>(Mutable) Return this Arrayy object, with re-indexed array-elements.</p>
2545
   */
2546 9
  public function reindex()
2547
  {
2548 9
    $this->array = \array_values($this->array);
2549
2550 9
    return $this;
2551
  }
2552
2553
  /**
2554
   * Return all items that fail the truth test.
2555
   *
2556
   * @param \Closure $closure
2557
   *
2558
   * @return static <p>(Immutable)</p>
2559
   */
2560 1 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...
2561
  {
2562 1
    $filtered = array();
2563
2564 1
    foreach ($this->array as $key => $value) {
2565 1
      if (!$closure($value, $key)) {
2566 1
        $filtered[$key] = $value;
2567 1
      }
2568 1
    }
2569
2570 1
    return static::create($filtered);
2571
  }
2572
2573
  /**
2574
   * Remove a value from the current array (optional using dot-notation).
2575
   *
2576
   * @param mixed $key
2577
   *
2578
   * @return static <p>(Immutable)</p>
2579
   */
2580 18
  public function remove($key)
2581
  {
2582
    // Recursive call
2583 18
    if (is_array($key)) {
2584
      foreach ($key as $k) {
2585
        $this->internalRemove($k);
2586
      }
2587
2588
      return static::create($this->array);
2589
    }
2590
2591 18
    $this->internalRemove($key);
2592
2593 18
    return static::create($this->array);
2594
  }
2595
2596
  /**
2597
   * Remove the first value from the current array.
2598
   *
2599
   * @return static <p>(Immutable)</p>
2600
   */
2601 7
  public function removeFirst()
2602
  {
2603 7
    $tmpArray = $this->array;
2604 7
    \array_shift($tmpArray);
2605
2606 7
    return static::create($tmpArray);
2607
  }
2608
2609
  /**
2610
   * Remove the last value from the current array.
2611
   *
2612
   * @return static <p>(Immutable)</p>
2613
   */
2614 7
  public function removeLast()
2615
  {
2616 7
    $tmpArray = $this->array;
2617 7
    \array_pop($tmpArray);
2618
2619 7
    return static::create($tmpArray);
2620
  }
2621
2622
  /**
2623
   * Removes a particular value from an array (numeric or associative).
2624
   *
2625
   * @param mixed $value
2626
   *
2627
   * @return static <p>(Immutable)</p>
2628
   */
2629 7
  public function removeValue($value)
2630
  {
2631 7
    $isNumericArray = true;
2632 7
    foreach ($this->array as $key => $item) {
2633 6
      if ($item === $value) {
2634 6
        if (!is_int($key)) {
2635
          $isNumericArray = false;
2636
        }
2637 6
        unset($this->array[$key]);
2638 6
      }
2639 7
    }
2640
2641 7
    if ($isNumericArray) {
2642 7
      $this->array = \array_values($this->array);
2643 7
    }
2644
2645 7
    return static::create($this->array);
2646
  }
2647
2648
  /**
2649
   * Generate array of repeated arrays.
2650
   *
2651
   * @param int $times <p>How many times has to be repeated.</p>
2652
   *
2653
   * @return Arrayy
2654
   */
2655 1
  public function repeat($times)
2656
  {
2657 1
    if ($times === 0) {
2658 1
      return new static();
2659
    }
2660
2661 1
    return static::create(\array_fill(0, (int)$times, $this->array));
2662
  }
2663
2664
  /**
2665
   * Replace a key with a new key/value pair.
2666
   *
2667
   * @param $replace
2668
   * @param $key
2669
   * @param $value
2670
   *
2671
   * @return static <p>(Immutable)</p>
2672
   */
2673 2
  public function replace($replace, $key, $value)
2674
  {
2675 2
    $this->remove($replace);
2676
2677 2
    return $this->set($key, $value);
2678
  }
2679
2680
  /**
2681
   * Create an array using the current array as values and the other array as keys.
2682
   *
2683
   * @param array $keys <p>An array of keys.</p>
2684
   *
2685
   * @return static <p>(Immutable) Arrayy object with keys from the other array.</p>
2686
   */
2687 2
  public function replaceAllKeys(array $keys)
2688
  {
2689 2
    $result = \array_combine($keys, $this->array);
2690
2691 2
    return static::create($result);
2692
  }
2693
2694
  /**
2695
   * Create an array using the current array as keys and the other array as values.
2696
   *
2697
   * @param array $array <p>An array o values.</p>
2698
   *
2699
   * @return static <p>(Immutable) Arrayy object with values from the other array.</p>
2700
   */
2701 2
  public function replaceAllValues(array $array)
2702
  {
2703 2
    $result = \array_combine($this->array, $array);
2704
2705 2
    return static::create($result);
2706
  }
2707
2708
  /**
2709
   * Replace the keys in an array with another set.
2710
   *
2711
   * @param array $keys <p>An array of keys matching the array's size</p>
2712
   *
2713
   * @return static <p>(Immutable)</p>
2714
   */
2715 1
  public function replaceKeys(array $keys)
2716
  {
2717 1
    $values = \array_values($this->array);
2718 1
    $result = \array_combine($keys, $values);
2719
2720 1
    return static::create($result);
2721
  }
2722
2723
  /**
2724
   * Replace the first matched value in an array.
2725
   *
2726
   * @param mixed $search
2727
   * @param mixed $replacement
2728
   *
2729
   * @return static <p>(Immutable)</p>
2730
   */
2731 3
  public function replaceOneValue($search, $replacement = '')
2732
  {
2733 3
    $array = $this->array;
2734 3
    $key = \array_search($search, $array, true);
2735
2736 3
    if ($key !== false) {
2737 3
      $array[$key] = $replacement;
2738 3
    }
2739
2740 3
    return static::create($array);
2741
  }
2742
2743
  /**
2744
   * Replace values in the current array.
2745
   *
2746
   * @param string $search      <p>The string to replace.</p>
2747
   * @param string $replacement <p>What to replace it with.</p>
2748
   *
2749
   * @return static <p>(Immutable)</p>
2750
   */
2751 1
  public function replaceValues($search, $replacement = '')
2752
  {
2753 1
    $array = $this->each(
2754
        function ($value) use ($search, $replacement) {
2755 1
          return UTF8::str_replace($search, $replacement, $value);
2756
        }
2757 1
    );
2758
2759 1
    return $array;
2760
  }
2761
2762
  /**
2763
   * Get the last elements from index $from until the end of this array.
2764
   *
2765
   * @param int $from
2766
   *
2767
   * @return static <p>(Immutable)</p>
2768
   */
2769 15
  public function rest($from = 1)
2770
  {
2771 15
    $tmpArray = $this->array;
2772
2773 15
    return static::create(\array_splice($tmpArray, $from));
2774
  }
2775
2776
  /**
2777
   * Return the array in the reverse order.
2778
   *
2779
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2780
   */
2781 8
  public function reverse()
2782
  {
2783 8
    $this->array = \array_reverse($this->array);
2784
2785 8
    return $this;
2786
  }
2787
2788
  /**
2789
   * Sort an array in reverse order.
2790
   *
2791
   * @param int $sort_flags [optional] <p>
2792
   *                        You may modify the behavior of the sort using the optional
2793
   *                        parameter sort_flags, for details
2794
   *                        see sort.
2795
   *                        </p>
2796
   *
2797
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2798
   */
2799 4
  public function rsort($sort_flags = null)
2800
  {
2801 4
    rsort($this->array, $sort_flags);
2802
2803 4
    return $this;
2804
  }
2805
2806
  /**
2807
   * Search for the first index of the current array via $value.
2808
   *
2809
   * @param mixed $value
2810
   *
2811
   * @return int|float|string
2812
   */
2813 20
  public function searchIndex($value)
2814
  {
2815 20
    return \array_search($value, $this->array, true);
2816
  }
2817
2818
  /**
2819
   * Search for the value of the current array via $index.
2820
   *
2821
   * @param mixed $index
2822
   *
2823
   * @return static <p>(Immutable) Will return a empty Arrayy if the value wasn't found.</p>
2824
   */
2825 9
  public function searchValue($index)
2826
  {
2827
    // init
2828 9
    $return = array();
2829
2830 9
    if ($this->isEmpty()) {
2831
      return static::create();
2832
    }
2833
2834
    // php cast "bool"-index into "int"-index
2835 9
    if ((bool)$index === $index) {
2836 1
      $index = (int)$index;
2837 1
    }
2838
2839 9
    if (\array_key_exists($index, $this->array) === true) {
2840 7
      $return = array($this->array[$index]);
2841 7
    }
2842
2843
2844 9
    return static::create($return);
2845
  }
2846
2847
  /**
2848
   * Set a value for the current array (optional using dot-notation).
2849
   *
2850
   * @param string $key   <p>The key to set.</p>
2851
   * @param mixed  $value <p>Its value.</p>
2852
   *
2853
   * @return static <p>(Immutable)</p>
2854
   */
2855 17
  public function set($key, $value)
2856
  {
2857 17
    $this->internalSet($key, $value);
2858
2859 17
    return static::create($this->array);
2860
  }
2861
2862
  /**
2863
   * Get a value from a array and set it if it was not.
2864
   *
2865
   * WARNING: this method only set the value, if the $key is not already set
2866
   *
2867
   * @param string $key      <p>The key</p>
2868
   * @param mixed  $fallback <p>The default value to set if it isn't.</p>
2869
   *
2870
   * @return mixed <p>(Mutable)</p>
2871
   */
2872 11
  public function setAndGet($key, $fallback = null)
2873
  {
2874
    // If the key doesn't exist, set it.
2875 11
    if (!$this->has($key)) {
2876 4
      $this->array = $this->set($key, $fallback)->getArray();
2877 4
    }
2878
2879 11
    return $this->get($key);
2880
  }
2881
2882
  /**
2883
   * Shifts a specified value off the beginning of array.
2884
   *
2885
   * @return mixed <p>(Mutable) A shifted element from the current array.</p>
2886
   */
2887 4
  public function shift()
2888
  {
2889 4
    return \array_shift($this->array);
2890
  }
2891
2892
  /**
2893
   * Shuffle the current array.
2894
   *
2895
   * @return static <p>(Immutable)</p>
2896
   */
2897 1
  public function shuffle()
2898
  {
2899 1
    $array = $this->array;
2900
2901 1
    shuffle($array);
2902
2903 1
    return static::create($array);
2904
  }
2905
2906
  /**
2907
   * Get the size of an array.
2908
   *
2909
   * @return int
2910
   */
2911 93
  public function size()
2912
  {
2913 93
    return count($this->array);
2914
  }
2915
2916
  /**
2917
   * Extract a slice of the array.
2918
   *
2919
   * @param int      $offset       <p>Slice begin index.</p>
2920
   * @param int|null $length       <p>Length of the slice.</p>
2921
   * @param bool     $preserveKeys <p>Whether array keys are preserved or no.</p>
2922
   *
2923
   * @return static <p>A slice of the original array with length $length.</p>
2924
   */
2925 4
  public function slice($offset, $length = null, $preserveKeys = false)
2926
  {
2927 4
    $result = \array_slice($this->array, $offset, $length, $preserveKeys);
2928
2929 4
    return static::create($result);
2930
  }
2931
2932
  /**
2933
   * Sort the current array and optional you can keep the keys.
2934
   *
2935
   * @param integer $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2936
   * @param integer $strategy  <p>sort_flags => use e.g.: <strong>SORT_REGULAR</strong> (default) or
2937
   *                           <strong>SORT_NATURAL</strong></p>
2938
   * @param bool    $keepKeys
2939
   *
2940
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2941
   */
2942 19
  public function sort($direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2943
  {
2944 19
    $this->sorting($this->array, $direction, $strategy, $keepKeys);
2945
2946 19
    return $this;
2947
  }
2948
2949
  /**
2950
   * Sort the current array by key.
2951
   *
2952
   * @link http://php.net/manual/en/function.ksort.php
2953
   * @link http://php.net/manual/en/function.krsort.php
2954
   *
2955
   * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2956
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
2957
   *                              <strong>SORT_NATURAL</strong></p>
2958
   *
2959
   * @return static <p>(Mutable) Return this Arrayy object.</p>
2960
   */
2961 18
  public function sortKeys($direction = SORT_ASC, $strategy = SORT_REGULAR)
2962
  {
2963 18
    $this->sorterKeys($this->array, $direction, $strategy);
2964
2965 18
    return $this;
2966
  }
2967
2968
  /**
2969
   * Sort the current array by value.
2970
   *
2971
   * @param int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2972
   * @param int $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2973
   *
2974
   * @return static <p>(Mutable)</p>
2975
   */
2976 1
  public function sortValueKeepIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2977
  {
2978 1
    return $this->sort($direction, $strategy, true);
2979
  }
2980
2981
  /**
2982
   * Sort the current array by value.
2983
   *
2984
   * @param int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
2985
   * @param int $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
2986
   *
2987
   * @return static <p>(Mutable)</p>
2988
   */
2989 1
  public function sortValueNewIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2990
  {
2991 1
    return $this->sort($direction, $strategy, false);
2992
  }
2993
2994
  /**
2995
   * Sort a array by value, by a closure or by a property.
2996
   *
2997
   * - If the sorter is null, the array is sorted naturally.
2998
   * - Associative (string) keys will be maintained, but numeric keys will be re-indexed.
2999
   *
3000
   * @param null       $sorter
3001
   * @param string|int $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
3002
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
3003
   *                              <strong>SORT_NATURAL</strong></p>
3004
   *
3005
   * @return static <p>(Immutable)</p>
3006
   */
3007 1
  public function sorter($sorter = null, $direction = SORT_ASC, $strategy = SORT_REGULAR)
3008
  {
3009 1
    $array = (array)$this->array;
3010 1
    $direction = $this->getDirection($direction);
3011
3012
    // Transform all values into their results.
3013 1
    if ($sorter) {
3014 1
      $arrayy = static::create($array);
3015
3016 1
      $that = $this;
3017 1
      $results = $arrayy->each(
3018
          function ($value) use ($sorter, $that) {
3019 1
            return is_callable($sorter) ? $sorter($value) : $that->get($sorter, null, $value);
3020
          }
3021 1
      );
3022
3023 1
      $results = $results->getArray();
3024 1
    } else {
3025 1
      $results = $array;
3026
    }
3027
3028
    // Sort by the results and replace by original values
3029 1
    \array_multisort($results, $direction, $strategy, $array);
3030
3031 1
    return static::create($array);
3032
  }
3033
3034
  /**
3035
   * sorting keys
3036
   *
3037
   * @param array $elements
3038
   * @param int   $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
3039
   * @param int   $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or <strong>SORT_NATURAL</strong></p>
3040
   *
3041
   * @return static <p>(Mutable) Return this Arrayy object.</p>
3042
   */
3043 18
  protected function sorterKeys(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR)
3044
  {
3045 18
    $direction = $this->getDirection($direction);
3046
3047
    switch ($direction) {
3048 18
      case 'desc':
3049 18
      case SORT_DESC:
3050 6
        krsort($elements, $strategy);
3051 6
        break;
3052 13
      case 'asc':
3053 13
      case SORT_ASC:
3054 13
      default:
3055 13
        ksort($elements, $strategy);
3056 13
    }
3057
3058 18
    return $this;
3059
  }
3060
3061
  /**
3062
   * @param array      &$elements
3063
   * @param int|string $direction <p>use <strong>SORT_ASC</strong> (default) or <strong>SORT_DESC</strong></p>
3064
   * @param int        $strategy  <p>use e.g.: <strong>SORT_REGULAR</strong> (default) or
3065
   *                              <strong>SORT_NATURAL</strong></p>
3066
   * @param bool       $keepKeys
3067
   *
3068
   * @return static <p>(Mutable) Return this Arrayy object.</p>
3069
   */
3070 19
  protected function sorting(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
3071
  {
3072 19
    $direction = $this->getDirection($direction);
3073
3074 19
    if (!$strategy) {
3075 19
      $strategy = SORT_REGULAR;
3076 19
    }
3077
3078
    switch ($direction) {
3079 19
      case 'desc':
3080 19
      case SORT_DESC:
3081 9
        if ($keepKeys) {
3082 5
          arsort($elements, $strategy);
3083 5
        } else {
3084 4
          rsort($elements, $strategy);
3085
        }
3086 9
        break;
3087 10
      case 'asc':
3088 10
      case SORT_ASC:
3089 10
      default:
3090 10
        if ($keepKeys) {
3091 4
          asort($elements, $strategy);
3092 4
        } else {
3093 6
          sort($elements, $strategy);
3094
        }
3095 10
    }
3096
3097 19
    return $this;
3098
  }
3099
3100
  /**
3101
   * Split an array in the given amount of pieces.
3102
   *
3103
   * @param int  $numberOfPieces
3104
   * @param bool $keepKeys
3105
   *
3106
   * @return static <p>(Immutable)</p>
3107
   */
3108 1
  public function split($numberOfPieces = 2, $keepKeys = false)
3109
  {
3110 1
    $arrayCount = $this->count();
3111
3112 1
    if ($arrayCount === 0) {
3113 1
      $result = array();
3114 1
    } else {
3115 1
      $numberOfPieces = (int)$numberOfPieces;
3116 1
      $splitSize = (int)ceil($arrayCount / $numberOfPieces);
3117 1
      $result = \array_chunk($this->array, $splitSize, $keepKeys);
3118
    }
3119
3120 1
    return static::create($result);
3121
  }
3122
3123
  /**
3124
   * Stripe all empty items.
3125
   *
3126
   * @return static <p>(Immutable)</p>
3127
   */
3128 1
  public function stripEmpty()
3129
  {
3130 1
    return $this->filter(
3131
        function ($item) {
3132 1
          if ($item === null) {
3133 1
            return false;
3134
          }
3135
3136 1
          return (bool)trim((string)$item);
3137
        }
3138 1
    );
3139
  }
3140
3141
  /**
3142
   * Swap two values between positions by key.
3143
   *
3144
   * @param string|int $swapA <p>a key in the array</p>
3145
   * @param string|int $swapB <p>a key in the array</p>
3146
   *
3147
   * @return static <p>(Immutable)</p>
3148
   */
3149 1
  public function swap($swapA, $swapB)
3150
  {
3151 1
    $array = $this->array;
3152
3153 1
    list($array[$swapA], $array[$swapB]) = array($array[$swapB], $array[$swapA]);
3154
3155 1
    return static::create($array);
3156
  }
3157
3158
  /**
3159
   * alias: for "Arrayy->getArray()"
3160
   *
3161
   * @see Arrayy::getArray()
3162
   */
3163 146
  public function toArray()
3164
  {
3165 146
    return $this->getArray();
3166
  }
3167
3168
  /**
3169
   * Convert the current array to JSON.
3170
   *
3171
   * @param null|int $options [optional] <p>e.g. JSON_PRETTY_PRINT</p>
3172
   * @param int      $depth   [optional] <p>Set the maximum depth. Must be greater than zero.</p>
3173
   *
3174
   * @return string
3175
   */
3176 6
  public function toJson($options = null, $depth = 512)
3177
  {
3178 6
    return UTF8::json_encode($this->array, $options, $depth);
3179
  }
3180
3181
  /**
3182
   * Implodes array to a string with specified separator.
3183
   *
3184
   * @param string $separator [optional] <p>The element's separator.</p>
3185
   *
3186
   * @return string <p>The string representation of array, separated by ",".</p>
3187
   */
3188 19
  public function toString($separator = ',')
3189
  {
3190 19
    return $this->implode($separator);
3191
  }
3192
3193
  /**
3194
   * Return a duplicate free copy of the current array.
3195
   *
3196
   * @return static <p>(Mutable)</p>
3197
   */
3198 9
  public function unique()
3199
  {
3200
    // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array
3201
3202 9
    $this->array = \array_reduce(
0 ignored issues
show
Documentation Bug introduced by
It seems like \array_reduce($this->arr...esultArray; }, array()) of type * is incompatible with the declared type array of property $array.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
3203 9
        $this->array,
3204
        function ($resultArray, $value) {
3205 8
          if (!in_array($value, $resultArray, true)) {
3206 8
            $resultArray[] = $value;
3207 8
          }
3208
3209 8
          return $resultArray;
3210 9
        },
3211 9
        array()
3212 9
    );
3213
3214 9 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...
3215
      $this->array = array();
3216
    } else {
3217 9
      $this->array = (array)$this->array;
3218
    }
3219
3220 9
    return $this;
3221
  }
3222
3223
  /**
3224
   * Return a duplicate free copy of the current array. (with the old keys)
3225
   *
3226
   * @return static <p>(Mutable)</p>
3227
   */
3228 9
  public function uniqueKeepIndex()
3229
  {
3230
    // INFO: \array_unique() can't handle e.g. "stdClass"-values in an array
3231
3232
    // init
3233 9
    $array = $this->array;
3234
3235 9
    $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...
3236 9
        \array_keys($array),
3237 9
        function ($resultArray, $key) use ($array) {
3238 8
          if (!in_array($array[$key], $resultArray, true)) {
3239 8
            $resultArray[$key] = $array[$key];
3240 8
          }
3241
3242 8
          return $resultArray;
3243 9
        },
3244 9
        array()
3245 9
    );
3246
3247 9 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...
3248
      $this->array = array();
3249
    } else {
3250 9
      $this->array = (array)$this->array;
3251
    }
3252
3253 9
    return $this;
3254
  }
3255
3256
  /**
3257
   * alias: for "Arrayy->unique()"
3258
   *
3259
   * @see Arrayy::unique()
3260
   *
3261
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
3262
   */
3263 9
  public function uniqueNewIndex()
3264
  {
3265 9
    return $this->unique();
3266
  }
3267
3268
  /**
3269
   * Prepends one or more values to the beginning of array at once.
3270
   *
3271
   * @return static <p>(Mutable) Return this Arrayy object, with prepended elements to the beginning of array.</p>
3272
   */
3273 4 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...
3274
  {
3275 4
    if (func_num_args()) {
3276 4
      $args = \array_merge(array(&$this->array), func_get_args());
3277 4
      call_user_func_array('array_unshift', $args);
3278 4
    }
3279
3280 4
    return $this;
3281
  }
3282
3283
  /**
3284
   * Get all values from a array.
3285
   *
3286
   * @return static <p>(Immutable)</p>
3287
   */
3288 2
  public function values()
3289
  {
3290 2
    return static::create(\array_values((array)$this->array));
3291
  }
3292
3293
  /**
3294
   * Apply the given function to every element in the array, discarding the results.
3295
   *
3296
   * @param callable $callable
3297
   * @param bool     $recursive <p>Whether array will be walked recursively or no</p>
3298
   *
3299
   * @return static <p>(Mutable) Return this Arrayy object, with modified elements.</p>
3300
   */
3301 9
  public function walk($callable, $recursive = false)
3302
  {
3303 9
    if (true === $recursive) {
3304 4
      \array_walk_recursive($this->array, $callable);
3305 4
    } else {
3306 5
      \array_walk($this->array, $callable);
3307
    }
3308
3309 9
    return $this;
3310
  }
3311
}
3312