Completed
Push — master ( 95bb75...4cfd42 )
by Lars
04:17
created

Arrayy::stripEmpty()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 1
nop 0
dl 0
loc 12
ccs 9
cts 9
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Arrayy;
4
5
use ArrayAccess;
6
use Closure;
7
use voku\helper\UTF8;
8
9
/**
10
 * Methods to manage arrays.
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
class Arrayy extends \ArrayObject
16
{
17
  /**
18
   * @var array
19
   */
20
  protected $array = array();
21
22
  /** @noinspection MagicMethodsValidityInspection */
23
  /**
24
   * Initializes
25
   *
26
   * @param array $array
27
   */
28 717
  public function __construct($array = array())
29
  {
30 717
    $array = $this->fallbackForArray($array);
31
32 715
    $this->array = $array;
0 ignored issues
show
Documentation Bug introduced by
It seems like $array can also be of type object<Arrayy\Arrayy>. However, the property $array is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
33 715
  }
34
35
  /**
36
   * Get a value by key.
37
   *
38
   * @param $key
39
   *
40
   * @return mixed Get a Value from the current array.
41
   */
42
  public function &__get($key)
43
  {
44
    return $this->array[$key];
45
  }
46
47
  /**
48
   * Call object as function.
49
   *
50
   * @param mixed $key
51
   *
52
   * @return mixed
53
   */
54
  public function __invoke($key = null)
55
  {
56
    if ($key !== null) {
57
      if (isset($this->array[$key])) {
58
        return $this->array[$key];
59
      } else {
60
        return false;
61
      }
62
    }
63
64
    return (array)$this->array;
65
  }
66
67
  /**
68
   * Whether or not an element exists by key.
69
   *
70
   * @param mixed $key
71
   *
72
   * @return bool True is the key/index exists, otherwise false.
73
   */
74
  public function __isset($key)
75
  {
76
    return isset($this->array[$key]);
77
  }
78
79
  /**
80
   * Assigns a value to the specified element.
81
   *
82
   * @param mixed $key
83
   * @param mixed $value
84
   */
85
  public function __set($key, $value)
86
  {
87
    $this->array[$key] = $value;
88
  }
89
90
  /**
91
   * magic to string
92
   *
93
   * @return string
94
   */
95 15
  public function __toString()
96
  {
97 15
    return $this->toString();
98
  }
99
100
  /**
101
   * Unset element by key.
102
   *
103
   * @param mixed $key
104
   */
105
  public function __unset($key)
106
  {
107
    unset($this->array[$key]);
108
  }
109
110
  /**
111
   * alias: for "Arrayy->append()"
112
   *
113
   * @param mixed $value
114
   *
115
   * @return self (Mutable) Return this Arrayy object, with the appended values.
116
   */
117 1
  public function add($value)
118
  {
119 1
    return $this->append($value);
120
  }
121
122
  /**
123
   * Append a value to the current array.
124
   *
125
   * @param mixed $value
126
   *
127
   * @return self (Mutable) Return this Arrayy object, with the appended values.
128
   */
129 9
  public function append($value)
130
  {
131 9
    $this->array[] = $value;
132
133 9
    return $this;
134
  }
135
136
  /**
137
   * Count the values from the current array.
138
   *
139
   * INFO: only a alias for "$arrayy->size()"
140
   *
141
   * @return int
142
   */
143 110
  public function count()
144
  {
145 110
    return $this->size();
146
  }
147
148
  /**
149
   * Returns a new ArrayIterator, thus implementing the IteratorAggregate interface.
150
   *
151
   * @return \ArrayIterator An iterator for the values in the array.
152
   */
153 17
  public function getIterator()
154
  {
155 17
    return new \ArrayIterator($this->array);
156
  }
157
158
  /**
159
   * Whether or not an offset exists.
160
   *
161
   * @param mixed $offset
162
   *
163
   * @return bool
164
   */
165 31
  public function offsetExists($offset)
166
  {
167 31
    return isset($this->array[$offset]);
168
  }
169
170
  /**
171
   * Returns the value at specified offset.
172
   *
173
   * @param mixed $offset
174
   *
175
   * @return mixed return null if the offset did not exists
176
   */
177 22
  public function offsetGet($offset)
178
  {
179 22
    return $this->offsetExists($offset) ? $this->array[$offset] : null;
180
  }
181
182
  /**
183
   * Assigns a value to the specified offset.
184
   *
185
   * @param mixed $offset
186
   * @param mixed $value
187
   */
188 13
  public function offsetSet($offset, $value)
189
  {
190 13
    if (null === $offset) {
191 4
      $this->array[] = $value;
192
    } else {
193 9
      $this->array[$offset] = $value;
194
    }
195 13
  }
196
197
  /**
198
   * Unset an offset.
199
   *
200
   * @param mixed $offset
201
   */
202 5
  public function offsetUnset($offset)
203
  {
204 5
    if ($this->offsetExists($offset)) {
205 3
      unset($this->array[$offset]);
206
    }
207 5
  }
208
209
  /**
210
   * Serialize the current array.
211
   *
212
   * @return string
213
   */
214 2
  public function serialize()
215
  {
216 2
    return serialize($this->array);
217
  }
218
219
  /**
220
   * Unserialize an string and return this object.
221
   *
222
   * @param string $string
223
   *
224
   * @return self (Mutable)
225
   */
226 2
  public function unserialize($string)
227
  {
228 2
    $this->array = unserialize($string);
229
230 2
    return $this;
231
  }
232
233
  /**
234
   * Iterate over the current array and execute a callback for each loop.
235
   *
236
   * @param \Closure $closure
237
   *
238
   * @return Arrayy (Immutable)
239
   */
240 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...
241
  {
242 2
    $array = $this->array;
243
244 2
    foreach ($array as $key => $value) {
245 2
      $closure($value, $key);
246
    }
247
248 2
    return static::create($array);
249
  }
250
251
  /**
252
   * Returns the average value of the current array.
253
   *
254
   * @param int $decimals The number of decimals to return
255
   *
256
   * @return int|double The average value
257
   */
258 10
  public function average($decimals = null)
259
  {
260 10
    $count = $this->count();
261
262 10
    if (!$count) {
263 2
      return 0;
264
    }
265
266 8
    if (!is_int($decimals)) {
267 3
      $decimals = null;
268
    }
269
270 8
    return round(array_sum($this->array) / $count, $decimals);
271
  }
272
273
  /**
274
   * Create a chunked version of the current array.
275
   *
276
   * @param int  $size         Size of each chunk
277
   * @param bool $preserveKeys Whether array keys are preserved or no
278
   *
279
   * @return Arrayy (Immutable) A new array of chunks from the original array.
280
   */
281 4
  public function chunk($size, $preserveKeys = false)
282
  {
283 4
    $result = array_chunk($this->array, $size, $preserveKeys);
284
285 4
    return static::create($result);
286
  }
287
288
  /**
289
   * Clean all falsy values from the current array.
290
   *
291
   * @return Arrayy (Immutable)
292
   */
293 8
  public function clean()
294
  {
295 8
    return $this->filter(
296
        function ($value) {
297 7
          return (bool)$value;
298 8
        }
299
    );
300
  }
301
302
  /**
303
   * WARNING!!! -> Clear the current array.
304
   *
305
   * @return self (Mutable) Return this Arrayy object, with an empty array.
306
   */
307 4
  public function clear()
308
  {
309 4
    $this->array = array();
310
311 4
    return $this;
312
  }
313
314
  /**
315
   * Check if an item is in the current array.
316
   *
317
   * @param mixed $value
318
   *
319
   * @return bool
320
   */
321 13
  public function contains($value)
322
  {
323 13
    return in_array($value, $this->array, true);
324
  }
325
326
  /**
327
   * Check if an (case-insensitive) string is in the current array.
328
   *
329
   * @param string $value
330
   *
331
   * @return bool
332
   */
333 13
  public function containsCaseInsensitive($value)
334
  {
335 13
    return in_array(
336 13
        UTF8::strtolower($value),
337
        array_map(
338
            array(
339 13
                new UTF8(),
340 13
                'strtolower',
341
            ),
342 13
            $this->array
343
        ),
344 13
        true
345
    );
346
  }
347
348
  /**
349
   * Check if the given key/index exists in the array.
350
   *
351
   * @param mixed $key Key/index to search for
352
   *
353
   * @return bool Returns true if the given key/index exists in the array, false otherwise
354
   */
355 4
  public function containsKey($key)
356
  {
357 4
    return $this->offsetExists($key);
358
  }
359
360
  /** @noinspection ArrayTypeOfParameterByDefaultValueInspection */
361
  /**
362
   * Creates an Arrayy object.
363
   *
364
   * @param array $array
365
   *
366
   * @return Arrayy (Immutable) Returns an new instance of the Arrayy object.
367
   */
368 444
  public static function create($array = array())
369
  {
370 444
    return new static($array);
371
  }
372
373
  /** @noinspection ArrayTypeOfParameterByDefaultValueInspection */
374
  /**
375
   * WARNING: Creates an Arrayy object by reference.
376
   *
377
   * @param array $array
378
   *
379
   * @return self (Mutable) Return this Arrayy object.
380
   */
381
  public function createByReference(&$array = array())
382
  {
383
    $array = $this->fallbackForArray($array);
384
385
    $this->array = &$array;
386
387
    return $this;
388
  }
389
390
  /**
391
   * Create an new Arrayy object via JSON.
392
   *
393
   * @param string $json
394
   *
395
   * @return Arrayy (Immutable) Returns an new instance of the Arrayy object.
396
   */
397 5
  public static function createFromJson($json)
398
  {
399 5
    $array = UTF8::json_decode($json, true);
400
401 5
    return static::create($array);
402
  }
403
404
  /**
405
   * Create an new instance filled with values from an object that have implemented ArrayAccess.
406
   *
407
   * @param ArrayAccess $object Object that implements ArrayAccess
408
   *
409
   * @return Arrayy (Immutable) Returns an new instance of the Arrayy object.
410
   */
411 4
  public static function createFromObject(ArrayAccess $object)
412
  {
413 4
    $array = new static();
414 4
    foreach ($object as $key => $value) {
415
      /** @noinspection OffsetOperationsInspection */
416 3
      $array[$key] = $value;
417
    }
418
419 4
    return $array;
420
  }
421
422
  /**
423
   * Create an new Arrayy object via string.
424
   *
425
   * @param string      $str       The input string.
426
   * @param string|null $delimiter The boundary string.
427
   * @param string|null $regEx     Use the $delimiter or the $regEx, so if $pattern is null, $delimiter will be used.
428
   *
429
   * @return Arrayy (Immutable) Returns an new instance of the Arrayy object.
430
   */
431 1
  public static function createFromString($str, $delimiter, $regEx = null)
432
  {
433 1
    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...
434
      preg_match_all($regEx, $str, $array);
435
436
      if (count($array) > 0) {
437
        $array = $array[0];
438
      }
439
440
    } else {
441
      $array = explode($delimiter, $str);
442
    }
443
444
    // trim all string in the array
445 8
    array_walk(
446
        $array,
447 8
        function (&$val) {
448 1
          /** @noinspection ReferenceMismatchInspection */
449
          if (is_string($val)) {
450 1
            $val = trim($val);
451 1
          }
452
        }
453
    );
454
455 7
    return static::create($array);
456
  }
457
458
  /**
459 8
   * Create an new instance containing a range of elements.
460
   *
461
   * @param mixed $low  First value of the sequence
462
   * @param mixed $high The sequence is ended upon reaching the end value
463 8
   * @param int   $step Used as the increment between elements in the sequence
464 8
   *
465
   * @return Arrayy (Immutable) Returns an new instance of the Arrayy object.
466 8
   */
467
  public static function createWithRange($low, $high, $step = 1)
468
  {
469 8
    return static::create(range($low, $high, $step));
470
  }
471
472
  /**
473
   * Custom sort by index via "uksort".
474
   *
475
   * @link http://php.net/manual/en/function.uksort.php
476
   *
477
   * @param callable $function
478
   *
479
   * @return self (Mutable) Return this Arrayy object.
480
   */
481 5
  public function customSortKeys($function)
482
  {
483 5
    uksort($this->array, $function);
484
485 5
    return $this;
486
  }
487
488
  /**
489
   * Custom sort by value via "usort".
490
   *
491
   * @link http://php.net/manual/en/function.usort.php
492
   *
493
   * @param callable $function
494
   *
495
   * @return self (Mutable) Return this Arrayy object.
496
   */
497 4
  public function customSortValues($function)
498
  {
499 4
    usort($this->array, $function);
500
501 4
    return $this;
502
  }
503
504
  /**
505
   * Return values that are only in the current array.
506
   *
507
   * @param array $array
508
   *
509
   * @return Arrayy (Immutable)
510
   */
511 12
  public function diff(array $array = array())
512
  {
513 12
    $result = array_diff($this->array, $array);
514
515 12
    return static::create($result);
516
  }
517
518
  /**
519
   * Return values that are only in the current multi-dimensional array.
520
   *
521
   * @param array      $array
522
   * @param null|array $helperVariableForRecursion (only for internal usage)
523
   *
524
   * @return Arrayy (Immutable)
525 8
   */
526
  public function diffRecursive(array $array = array(), $helperVariableForRecursion = null)
527 8
  {
528
    $result = array();
529 8
530
    if ($helperVariableForRecursion !== null && is_array($helperVariableForRecursion) === true) {
531
      $arrayForTheLoop = $helperVariableForRecursion;
532
    } else {
533
      $arrayForTheLoop = $this->array;
534
    }
535
536
    foreach ($arrayForTheLoop as $key => $value) {
537
      if (array_key_exists($key, $array)) {
538
        if (is_array($value)) {
539
          $recursiveDiff = $this->diffRecursive($array[$key], $value);
540 1
          if (count($recursiveDiff)) {
541
            $result[$key] = $recursiveDiff;
542 1
          }
543
        } else {
544 1
          if ($value != $array[$key]) {
545 1
            $result[$key] = $value;
546
          }
547 1
        }
548
      } else {
549
        $result[$key] = $value;
550 1
      }
551 1
    }
552 1
553 1
    return static::create($result);
554 1
  }
555 1
556
  /**
557
   * Return values that are only in the new $array.
558 1
   *
559 1
   * @param array $array
560
   *
561
   * @return Arrayy (Immutable)
562
   */
563 1
  public function diffReverse(array $array = array())
564
  {
565
    $result = array_diff($array, $this->array);
566
567 1
    return static::create($result);
568
  }
569
570
  /**
571
   * Divide an array into two arrays. One with keys and the other with values.
572
   *
573
   * @return Arrayy (Immutable)
574
   */
575
  public function divide()
576
  {
577 22
    return static::create(
578
        array(
579 22
            $this->keys(),
580
            $this->values(),
581 22
        )
582 18
    );
583
  }
584
585 22
  /**
586
   * Iterate over the current array and modify the array's value.
587
   *
588
   * @param \Closure $closure
589
   *
590
   * @return Arrayy (Immutable)
591
   */
592 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...
593
  {
594
    $array = $this->array;
595 4
596
    foreach ($array as $key => &$value) {
597 4
      $value = $closure($value, $key);
598 4
    }
599 3
600 1
    return static::create($array);
601 3
  }
602
603
  /**
604
   * Check if a value is in the current array using a closure.
605 4
   *
606
   * @param \Closure $closure
607
   *
608
   * @return bool Returns true if the given value is found, false otherwise
609
   */
610
  public function exists(\Closure $closure)
611
  {
612
    $isExists = false;
613
    foreach ($this->array as $key => $value) {
614
      if ($closure($value, $key)) {
615
        $isExists = true;
616
        break;
617
      }
618
    }
619
620
    return $isExists;
621
  }
622
623
  /**
624
   * create a fallback for array
625 717
   *
626
   * 1. use the current array, if it's a array
627 717
   * 2. call "getArray()" on object, if there is a "Arrayy"-object
628 714
   * 3. fallback to empty array, if there is nothing
629
   * 4. call "createFromObject()" on object, if there is a "ArrayAccess"-object
630
   * 5. call "__toArray()" on object, if the method exists
631 9
   * 6. cast a string or object with "__toString()" into an array
632
   * 7. throw a "InvalidArgumentException"-Exception
633
   *
634
   * @param $array
635 9
   *
636 6
   * @return array
637
   *
638
   * @throws \InvalidArgumentException
639 8
   */
640
  protected function fallbackForArray(&$array)
641
  {
642
    if (is_array($array)) {
643
      return $array;
644 8
    }
645
646
    if ($array instanceof self) {
647
      return $array->getArray();
648
    }
649
650 8
    if (!$array) {
651
      return array();
652 8
    }
653
654 6
    if ($array instanceof ArrayAccess) {
655
      /** @noinspection ReferenceMismatchInspection */
656
      return self::createFromObject($array);
657 2
    }
658 2
659
    if (is_object($array) && method_exists($array, '__toArray')) {
660
      return (array)$array->__toArray();
661
    }
662
663
    /** @noinspection ReferenceMismatchInspection */
664
    if (
665
        is_string($array)
666
        ||
667
        (is_object($array) && method_exists($array, '__toString'))
668
    ) {
669 8
      return (array)$array;
670
    }
671 8
672 1
    throw new \InvalidArgumentException(
673
        'Passed value should be a array'
674
    );
675 8
  }
676
677 8
  /**
678
   * Find all items in an array that pass the truth test.
679
   *
680
   * @param \Closure|null $closure
681
   *
682
   * @return Arrayy (Immutable)
683
   */
684
  public function filter($closure = null)
685
  {
686
    if (!$closure) {
687
      return $this->clean();
688
    }
689
690
    $array = array_filter($this->array, $closure);
691
692
    return static::create($array);
693
  }
694
695
  /**
696
   * Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property
697
   * within that.
698
   *
699
   * @param        $property
700 1
   * @param        $value
701
   * @param string $comparisonOp
702 1
   *                            'eq' (equals),<br />
703 1
   *                            'gt' (greater),<br />
704
   *                            'gte' || 'ge' (greater or equals),<br />
705
   *                            'lt' (less),<br />
706
   *                            'lte' || 'le' (less or equals),<br />
707
   *                            'ne' (not equals),<br />
708 1
   *                            'contains',<br />
709 1
   *                            'notContains',<br />
710
   *                            'newer' (via strtotime),<br />
711
   *                            'older' (via strtotime),<br />
712 1
   *
713
   * @return Arrayy (Immutable)
714
   */
715 1
  public function filterBy($property, $value, $comparisonOp = null)
716
  {
717
    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...
718 1
      $comparisonOp = is_array($value) ? 'contains' : 'eq';
719
    }
720 1
721 1
    $ops = array(
722
        'eq'          => function ($item, $prop, $value) {
723
          return $item[$prop] === $value;
724 1
        },
725
        'gt'          => function ($item, $prop, $value) {
726
          return $item[$prop] > $value;
727 1
        },
728
        'ge'          => function ($item, $prop, $value) {
729
          return $item[$prop] >= $value;
730 1
        },
731
        'gte'         => function ($item, $prop, $value) {
732 1
          return $item[$prop] >= $value;
733 1
        },
734
        'lt'          => function ($item, $prop, $value) {
735
          return $item[$prop] < $value;
736 1
        },
737
        'le'          => function ($item, $prop, $value) {
738
          return $item[$prop] <= $value;
739 1
        },
740
        'lte'         => function ($item, $prop, $value) {
741
          return $item[$prop] <= $value;
742 1
        },
743
        'ne'          => function ($item, $prop, $value) {
744
          return $item[$prop] !== $value;
745 1
        },
746
        'contains'    => function ($item, $prop, $value) {
747 1
          return in_array($item[$prop], (array)$value, true);
748
        },
749 1
        'notContains' => function ($item, $prop, $value) {
750 1
          return !in_array($item[$prop], (array)$value, true);
751 1
        },
752 1
        'newer'       => function ($item, $prop, $value) {
753
          return strtotime($item[$prop]) > strtotime($value);
754 1
        },
755 1
        'older'       => function ($item, $prop, $value) {
756 1
          return strtotime($item[$prop]) < strtotime($value);
757
        },
758 1
    );
759 1
760
    $result = array_values(
761
        array_filter(
762
            (array)$this->array,
763 1
            function ($item) use (
764
                $property,
765
                $value,
766
                $ops,
767
                $comparisonOp
768
            ) {
769
              $item = (array)$item;
770
              $itemArrayy = new Arrayy($item);
771
              $item[$property] = $itemArrayy->get($property, array());
772
773
              return $ops[$comparisonOp]($item, $property, $value);
774 8
            }
775
        )
776 8
    );
777 6
778 6
    return static::create($result);
779
  }
780
781
  /**
782 3
   * Find the first item in an array that passes the truth test,
783
   *  otherwise return false
784
   *
785
   * @param \Closure $closure
786
   *
787
   * @return mixed|false false if we did not find the value
788
   */
789
  public function find(\Closure $closure)
790
  {
791
    foreach ($this->array as $key => $value) {
792
      if ($closure($value, $key)) {
793
        return $value;
794
      }
795
    }
796
797
    return false;
798
  }
799
800
  /**
801
   * find by ...
802
   *
803
   * @param        $property
804 13
   * @param        $value
805
   * @param string $comparisonOp
806 13
   *
807
   * @return Arrayy (Immutable)
808 13
   */
809 3
  public function findBy($property, $value, $comparisonOp = 'eq')
810
  {
811 10
    return $this->filterBy($property, $value, $comparisonOp);
812
  }
813
814
  /**
815
   * Get the first value from the current array.
816
   *
817
   * @return mixed Return null if there wasn't a element.
818
   */
819
  public function first()
820
  {
821
    $result = array_shift($this->array);
822 26
823
    if (null === $result) {
824 26
      return null;
825 11
    } else {
826
      return $result;
827 15
    }
828 15
  }
829
830
  /**
831 26
   * Get the first value(s) from the current array.
832
   *
833
   * @param int|null $number how many values you will take?
834
   *
835
   * @return Arrayy (Immutable)
836
   */
837
  public function firstsImmutable($number = null)
838
  {
839
    if ($number === null) {
840
      $array = (array)array_shift($this->array);
841 28
    } else {
842
      $number = (int)$number;
843 28
      $array = array_splice($this->array, 0, $number, true);
844 7
    }
845
846 21
    return static::create($array);
847 21
  }
848
849
  /**
850 28
   * Get the first value(s) from the current array.
851
   *
852
   * @param int|null $number how many values you will take?
853
   *
854
   * @return self (Mutable)
855
   */
856
  public function firstsMutable($number = null)
857
  {
858 1
    if ($number === null) {
859
      $this->array = (array)array_shift($this->array);
860 1
    } else {
861
      $number = (int)$number;
862 1
      $this->array = array_splice($this->array, 0, $number, true);
863
    }
864
865
    return $this;
866
  }
867
868
  /**
869
   * Exchanges all keys with their associated values in an array.
870
   *
871
   * @return Arrayy (Immutable)
872
   */
873
  public function flip()
874 34
  {
875
    $result = array_flip($this->array);
876 34
877 3
    return static::create($result);
878
  }
879 32
880
  /**
881
   * Get a value from an array (optional using dot-notation).
882 34
   *
883 1
   * @param string $key     The key to look for.
884
   * @param mixed  $default Default value to fallback to.
885
   * @param array  $array   The array to get from, if it's set to "null" we use the current array from the class.
886 34
   *
887 23
   * @return mixed
888
   */
889
  public function get($key, $default = null, $array = null)
890
  {
891 19
    if (is_array($array) === true) {
892 19
      $usedArray = $array;
893 17
    } else {
894
      $usedArray = $this->array;
895
    }
896 2
897
    if (null === $key) {
898
      return $usedArray;
899 2
    }
900
901
    if (isset($usedArray[$key])) {
902
      return $usedArray[$key];
903
    }
904
905
    // Crawl through array, get key according to object or not
906
    foreach (explode('.', $key) as $segment) {
907 475
      if (!isset($usedArray[$segment])) {
908
        return $default instanceof Closure ? $default() : $default;
909 475
      }
910
911
      $usedArray = $usedArray[$segment];
912
    }
913
914
    return $usedArray;
915
  }
916
917
  /**
918
   * Get the current array from the "Arrayy"-object.
919
   *
920
   * @return array
921
   */
922
  public function getArray()
923
  {
924 1
    return $this->array;
925
  }
926 1
927
  /**
928 1
   * Returns the values from a single column of the input array, identified by
929
   * the $columnKey, can be used to extract data-columns from multi-arrays.
930
   *
931
   * Info: Optionally, you may provide an $indexKey to index the values in the returned
932
   * array by the values from the $indexKey column in the input array.
933
   *
934
   * @param mixed $columnKey
935
   * @param mixed $indexKey
936
   *
937
   * @return Arrayy (Immutable)
938 38
   */
939
  public function getColumn($columnKey = null, $indexKey = null)
940 38
  {
941 10
    $result = array_column($this->array, $columnKey, $indexKey);
942
943 10
    return static::create($result);
0 ignored issues
show
Bug introduced by
It seems like $result defined by array_column($this->array, $columnKey, $indexKey) on line 941 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...
944 2
  }
945
946 8
  /**
947
   * Get correct PHP constant for direction.
948
   *
949
   * @param int|string $direction
950
   *
951 38
   * @return int
952
   */
953 38
  protected function getDirection($direction)
954
  {
955
    if (is_string($direction)) {
956
      $direction = strtolower($direction);
957
958 38
      if ($direction === 'desc') {
959
        $direction = SORT_DESC;
960
      } else {
961
        $direction = SORT_ASC;
962
      }
963
    }
964
965
    if (
966
        $direction !== SORT_DESC
967
        &&
968
        $direction !== SORT_ASC
969
    ) {
970
      $direction = SORT_ASC;
971
    }
972
973
    return $direction;
974
  }
975
976 3
  /**
977
   * alias: for "Arrayy->keys()"
978 3
   *
979
   * @return Arrayy (Immutable)
980
   */
981
  public function getKeys()
982
  {
983
    return $this->keys();
984
  }
985
986 3
  /**
987
   * alias: for "Arrayy->random()"
988 3
   *
989
   * @return Arrayy (Immutable)
990
   */
991
  public function getRandom()
992
  {
993
    return $this->randomImmutable();
994
  }
995
996
  /**
997
   * alias: for "Arrayy->randomKey()"
998 9
   *
999
   * @return mixed get a key/index or null if there wasn't a key/index
1000 9
   */
1001
  public function getRandomKey()
1002
  {
1003
    return $this->randomKey();
1004
  }
1005
1006
  /**
1007
   * alias: for "Arrayy->randomKeys()"
1008 3
   *
1009
   * @param int $number
1010 3
   *
1011
   * @return Arrayy (Immutable)
1012
   */
1013
  public function getRandomKeys($number)
1014
  {
1015
    return $this->randomKeys($number);
1016
  }
1017
1018
  /**
1019
   * alias: for "Arrayy->randomValue()"
1020 6
   *
1021
   * @return mixed get a random value or null if there wasn't a value
1022 6
   */
1023
  public function getRandomValue()
1024
  {
1025
    return $this->randomValue();
1026
  }
1027
1028
  /**
1029
   * alias: for "Arrayy->randomValues()"
1030
   *
1031
   * @param int $number
1032
   *
1033 3
   * @return Arrayy (Immutable)
1034
   */
1035 3
  public function getRandomValues($number)
1036 3
  {
1037
    return $this->randomValues($number);
1038
  }
1039 3
1040 3
  /**
1041 3
   * Group values from a array according to the results of a closure.
1042
   *
1043
   * @param string $grouper a callable function name
1044 3
   * @param bool   $saveKeys
1045 2
   *
1046 1
   * @return Arrayy (Immutable)
1047 1
   */
1048
  public function group($grouper, $saveKeys = false)
1049 1
  {
1050 3
    $array = (array)$this->array;
1051
    $result = array();
1052
1053
    // Iterate over values, group by property/results from closure
1054
    foreach ($array as $key => $value) {
1055
      $groupKey = is_callable($grouper) ? $grouper($value, $key) : $this->get($grouper, null, $value);
1056 3
      $newValue = $this->get($groupKey, null, $result);
1057
1058
      // Add to results
1059
      if ($groupKey !== null) {
1060
        if ($saveKeys) {
1061
          $result[$groupKey] = $newValue;
1062
          $result[$groupKey][$key] = $value;
1063
        } else {
1064
          $result[$groupKey] = $newValue;
1065
          $result[$groupKey][] = $value;
1066 19
        }
1067
      }
1068
1069 19
    }
1070
1071 19
    return static::create($result);
1072
  }
1073
1074
  /**
1075
   * Check if an array has a given key.
1076
   *
1077
   * @param mixed $key
1078
   *
1079
   * @return bool
1080
   */
1081 23
  public function has($key)
1082
  {
1083 23
    // Generate unique string to use as marker.
1084
    $unFound = (string)uniqid('arrayy', true);
1085
1086
    return $this->get($key, $unFound) !== $unFound;
1087
  }
1088
1089
  /**
1090
   * Implodes an array.
1091
   *
1092
   * @param string $with What to implode it with
1093
   *
1094
   * @return string
1095
   */
1096
  public function implode($with = '')
1097 3
  {
1098
    return implode($with, $this->array);
1099 3
  }
1100
1101 3
  /**
1102 3
   * Given a list and an iterate-function that returns
1103 3
   * a key for each element in the list (or a property name),
1104
   * returns an object with an index of each item.
1105
   *
1106
   * Just like groupBy, but for when you know your keys are unique.
1107 3
   *
1108
   * @param mixed $key
1109
   *
1110
   * @return Arrayy (Immutable)
1111
   */
1112
  public function indexBy($key)
1113
  {
1114
    $results = array();
1115
1116
    foreach ($this->array as $a) {
1117 4
      if (isset($a[$key])) {
1118
        $results[$a[$key]] = $a;
1119 4
      }
1120
    }
1121
1122
    return static::create($results);
1123
  }
1124
1125
  /**
1126
   * alias: for "Arrayy->searchIndex()"
1127
   *
1128
   * @param mixed $value Value to search for
1129 12
   *
1130
   * @return mixed
1131 12
   */
1132
  public function indexOf($value)
1133 12
  {
1134
    return $this->searchIndex($value);
1135
  }
1136
1137
  /**
1138
   * Get everything but the last..$to items.
1139
   *
1140
   * @param int $to
1141
   *
1142
   * @return Arrayy (Immutable)
1143 18
   */
1144
  public function initial($to = 1)
1145
  {
1146 18
    $slice = count($this->array) - $to;
1147
1148
    return $this->firstsImmutable($slice);
1149 18
  }
1150
1151
  /**
1152
   * Internal mechanics of remove method.
1153
   *
1154
   * @param $key
1155
   *
1156
   * @return boolean
1157
   */
1158
  protected function internalRemove($key)
1159 18
  {
1160
    // Explode keys
1161 18
    $keys = explode('.', $key);
1162
1163 18
    // Crawl though the keys
1164
    while (count($keys) > 1) {
1165
      $key = array_shift($keys);
1166
1167
      if (!$this->has($key)) {
1168
        return false;
1169
      }
1170
1171
      $this->array = &$this->array[$key];
1172
    }
1173
1174 17
    $key = array_shift($keys);
1175
1176 17
    unset($this->array[$key]);
1177
1178
    return true;
1179
  }
1180
1181 17
  /**
1182
   * Internal mechanic of set method.
1183
   *
1184 17
   * @param string $key
1185
   * @param mixed  $value
1186
   *
1187 17
   * @return bool
1188 1
   */
1189
  protected function internalSet($key, $value)
1190
  {
1191
    if (null === $key) {
1192 1
      return false;
1193
    }
1194
1195 1
    // init
1196
    $array = &$this->array;
1197
1198 17
    // Explode the keys
1199
    $keys = explode('.', $key);
1200 17
1201
    // Crawl through the keys
1202
    while (count($keys) > 1) {
1203
      $key = array_shift($keys);
1204
      // If the key doesn't exist at this depth, we will just create an empty array
1205
      // to hold the next value, allowing us to create the arrays to hold final
1206
      // values at the correct depth. Then we'll keep digging into the array.
1207
      if (!isset($array[$key]) || !is_array($array[$key])) {
1208
        $array[$key] = array();
1209
      }
1210 2
      $array = &$array[$key];
1211
    }
1212 2
1213
    $array[array_shift($keys)] = $value;
1214 2
1215
    return true;
1216
  }
1217
1218
  /**
1219
   * Return an array with all elements found in input array.
1220
   *
1221
   * @param array $search
1222
   *
1223
   * @return Arrayy (Immutable)
1224 1
   */
1225
  public function intersection(array $search)
1226 1
  {
1227
    return static::create(array_values(array_intersect($this->array, $search)));
1228
  }
1229
1230
  /** @noinspection ArrayTypeOfParameterByDefaultValueInspection */
1231
1232
  /**
1233
   * Return a boolean flag which indicates whether the two input arrays have any common elements.
1234
   *
1235
   * @param array $search
1236
   *
1237
   * @return bool
1238 1
   */
1239
  public function intersects(array $search)
1240
  {
1241 1
    return count($this->intersection($search)->array) > 0;
1242 1
  }
1243
1244
  /**
1245
   * Invoke a function on all of an array's values.
1246 1
   *
1247 1
   * @param mixed $callable
1248
   * @param mixed $arguments
1249 1
   *
1250
   * @return Arrayy (Immutable)
1251
   */
1252 1
  public function invoke($callable, $arguments = array())
1253
  {
1254
    // If one argument given for each iteration, create an array for it.
1255
    if (!is_array($arguments)) {
1256
      $arguments = StaticArrayy::repeat($arguments, count($this->array))->getArray();
1257
    }
1258
1259
    // If the callable has arguments, pass them.
1260 15
    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...
1261
      $array = array_map($callable, $this->array, $arguments);
1262 15
    } else {
1263 3
      $array = array_map($callable, $this->array);
1264
    }
1265
1266 13
    return static::create($array);
1267 13
  }
1268 13
1269
  /**
1270
   * Check whether array is associative or not.
1271
   *
1272 3
   * @return bool Returns true if associative, false otherwise
1273
   */
1274
  public function isAssoc()
1275
  {
1276
    if ($this->isEmpty()) {
1277
      return false;
1278
    }
1279
1280 25
    foreach ($this->keys()->getArray() as $key) {
1281
      if (!is_string($key)) {
1282 25
        return false;
1283
      }
1284
    }
1285
1286
    return true;
1287
  }
1288
1289
  /**
1290 14
   * Check whether the array is empty or not.
1291
   *
1292 14
   * @return bool Returns true if empty, false otherwise
1293
   */
1294
  public function isEmpty()
1295
  {
1296
    return !$this->array;
1297
  }
1298
1299
  /**
1300 1
   * Check if the current array is equal to the given "$array" or not.
1301
   *
1302 1
   * @param array $array
1303
   *
1304
   * @return bool
1305
   */
1306
  public function isEqual(array $array)
1307
  {
1308
    return ($this->array === $array);
1309
  }
1310
1311
  /**
1312
   * Check if the current array is a multi-array.
1313
   *
1314
   * @return bool
1315
   */
1316
  public function isMultiArray()
1317
  {
1318
    return !(count($this->array) === count($this->array, COUNT_RECURSIVE));
1319
  }
1320
1321
  /**
1322 5
   * Check whether array is numeric or not.
1323
   *
1324 5
   * @return bool Returns true if numeric, false otherwise
1325 2
   */
1326
  public function isNumeric()
1327
  {
1328 4
    if ($this->isEmpty()) {
1329 4
      return false;
1330 4
    }
1331
1332
    foreach ($this->keys() as $key) {
1333
      if (!is_int($key)) {
1334 2
        return false;
1335
      }
1336
    }
1337
1338
    return true;
1339
  }
1340
1341
  /**
1342 22
   * Check if the current array is sequential [0, 1, 2, 3, 4, 5 ...] or not.
1343
   *
1344 22
   * @return bool
1345
   */
1346 22
  public function isSequential()
1347
  {
1348
    return array_keys($this->array) === range(0, count($this->array) - 1);
1349
  }
1350
1351
  /**
1352
   * Get all keys from the current array.
1353
   *
1354 4
   * @return Arrayy (Immutable)
1355
   */
1356 4
  public function keys()
1357
  {
1358 4
    return static::create(array_keys((array)$this->array));
1359 1
  }
1360
1361 3
  /**
1362
   * Get the last value from the current array.
1363
   *
1364
   * @return mixed Return null if there wasn't a element.
1365
   */
1366
  public function last()
1367
  {
1368
    $result = $this->pop();
1369
1370
    if (null === $result) {
1371
      return null;
1372 12
    } else {
1373
      return $result;
1374 12
    }
1375 8
  }
1376 8
1377
  /**
1378 4
   * Get the last value(s) from the current array.
1379 4
   *
1380
   * @param int|null $number
1381
   *
1382 12
   * @return Arrayy (Immutable)
1383
   */
1384
  public function lastsImmutable($number = null)
1385
  {
1386
    if ($number === null) {
1387
      $poppedValue = (array)$this->pop();
1388
      $arrayy = static::create($poppedValue);
1389
    } else {
1390
      $number = (int)$number;
1391
      $arrayy = $this->rest(-$number);
1392 12
    }
1393
1394 12
    return $arrayy;
1395 8
  }
1396 8
1397
  /**
1398 4
   * Get the last value(s) from the current array.
1399 4
   *
1400
   * @param int|null $number
1401
   *
1402 12
   * @return self (Mutable)
1403
   */
1404
  public function lastsMutable($number = null)
1405
  {
1406
    if ($number === null) {
1407
      $poppedValue = (array)$this->pop();
1408
      $this->array = static::create($poppedValue)->array;
1409
    } else {
1410
      $number = (int)$number;
1411
      $this->array = $this->rest(-$number)->array;
1412 10
    }
1413
1414 10
    return $this;
1415
  }
1416
1417
  /**
1418
   * Count the values from the current array.
1419
   *
1420
   * INFO: only a alias for "$arrayy->size()"
1421
   *
1422
   * @return int
1423
   */
1424
  public function length()
1425 4
  {
1426
    return $this->size();
1427 4
  }
1428
1429 4
  /**
1430
   * Apply the given function to the every element of the array,
1431
   * collecting the results.
1432
   *
1433
   * @param callable $callable
1434
   *
1435
   * @return Arrayy (Immutable) Arrayy object with modified elements
1436
   */
1437
  public function map($callable)
1438
  {
1439 9
    $result = array_map($callable, $this->array);
1440
1441
    return static::create($result);
1442 9
  }
1443
1444
  /**
1445 9
   * Check if all items in current array match a truth test.
1446 2
   *
1447
   * @param \Closure $closure
1448
   *
1449 7
   * @return bool
1450
   */
1451 7 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...
1452
  {
1453
    // Reduce the array to only booleans
1454
    $array = $this->each($closure);
1455
1456
    // Check the results
1457
    if (count($array) === 0) {
1458
      return true;
1459
    }
1460
1461 9
    $array = array_search(false, $array->toArray(), false);
1462
1463
    return is_bool($array);
1464 9
  }
1465
1466
  /**
1467 9
   * Check if any item in the current array matches a truth test.
1468 2
   *
1469
   * @param \Closure $closure
1470
   *
1471 7
   * @return bool
1472
   */
1473 7 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...
1474
  {
1475
    // Reduce the array to only booleans
1476
    $array = $this->each($closure);
1477
1478
    // Check the results
1479
    if (count($array) === 0) {
1480
      return true;
1481 10
    }
1482
1483 10
    $array = array_search(true, $array->toArray(), false);
1484 1
1485
    return is_int($array);
1486
  }
1487 9
1488
  /**
1489
   * Get the max value from an array.
1490
   *
1491
   * @return mixed
1492
   */
1493
  public function max()
1494
  {
1495
    if ($this->count() === 0) {
1496
      return false;
1497
    }
1498
1499
    return max($this->array);
1500 25
  }
1501
1502 25
  /**
1503 4
   * Merge the new $array into the current array.
1504
   *
1505 21
   * - keep key,value from the current array, also if the index is in the new $array
1506
   *
1507
   * @param array $array
1508 25
   * @param bool  $recursive
1509
   *
1510
   * @return Arrayy (Immutable)
1511
   */
1512 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...
1513
  {
1514
    if (true === $recursive) {
1515
      $result = array_replace_recursive($this->array, $array);
1516
    } else {
1517
      $result = array_replace($this->array, $array);
1518
    }
1519
1520
    return static::create($result);
1521
  }
1522 16
1523
  /**
1524 16
   * Merge the new $array into the current array.
1525 4
   *
1526
   * - replace duplicate assoc-keys from the current array with the key,values from the new $array
1527 12
   * - create new indexes
1528
   *
1529
   * @param array $array
1530 16
   * @param bool  $recursive
1531
   *
1532
   * @return Arrayy (Immutable)
1533
   */
1534 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...
1535
  {
1536
    if (true === $recursive) {
1537
      $result = array_merge_recursive($this->array, $array);
1538
    } else {
1539
      $result = array_merge($this->array, $array);
1540
    }
1541
1542
    return static::create($result);
1543 16
  }
1544
1545 16
  /**
1546 4
   * Merge the the current array into the $array.
1547
   *
1548 12
   * - use key,value from the new $array, also if the index is in the current array
1549
   *
1550
   * @param array $array
1551 16
   * @param bool  $recursive
1552
   *
1553
   * @return Arrayy (Immutable)
1554
   */
1555 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...
1556
  {
1557
    if (true === $recursive) {
1558
      $result = array_replace_recursive($array, $this->array);
1559
    } else {
1560
      $result = array_replace($array, $this->array);
1561
    }
1562
1563
    return static::create($result);
1564
  }
1565 16
1566
  /**
1567 16
   * Merge the current array into the new $array.
1568 4
   *
1569
   * - replace duplicate assoc-keys from new $array with the key,values from the current array
1570 12
   * - create new indexes
1571
   *
1572
   * @param array $array
1573 16
   * @param bool  $recursive
1574
   *
1575
   * @return Arrayy (Immutable)
1576
   */
1577 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...
1578
  {
1579
    if (true === $recursive) {
1580
      $result = array_merge_recursive($array, $this->array);
1581 10
    } else {
1582
      $result = array_merge($array, $this->array);
1583 10
    }
1584 1
1585
    return static::create($result);
1586
  }
1587 9
1588
  /**
1589
   * Get the min value from an array.
1590
   *
1591
   * @return mixed
1592
   */
1593
  public function min()
1594
  {
1595
    if ($this->count() === 0) {
1596
      return false;
1597
    }
1598 4
1599
    return min($this->array);
1600 4
  }
1601
1602 4
  /**
1603
   * Get a subset of the items from the given array.
1604
   *
1605
   * @param mixed[] $keys
1606
   *
1607
   * @return Arrayy (Immutable)
1608
   */
1609
  public function only(array $keys)
1610 16
  {
1611
    $array = $this->array;
1612 16
1613
    return static::create(array_intersect_key($array, array_flip($keys)));
1614
  }
1615
1616
  /**
1617
   * Pad array to the specified size with a given value.
1618
   *
1619
   * @param int   $size  Size of the result array
1620
   * @param mixed $value Empty value by default
1621
   *
1622 7
   * @return Arrayy (Immutable) Arrayy object padded to $size with $value
1623
   */
1624 7
  public function pad($size, $value)
1625
  {
1626 7
    $result = array_pad($this->array, $size, $value);
1627
1628
    return static::create($result);
1629
  }
1630
1631
  /**
1632
   * Pop a specified value off the end of the current array.
1633
   *
1634 4
   * @return mixed The popped element from the current array.
1635
   */
1636 4
  public function pop()
1637 4
  {
1638 4
    return array_pop($this->array);
1639
  }
1640
1641 4
  /**
1642
   * Prepend a value to the current array.
1643
   *
1644
   * @param mixed $value
1645
   * @param mixed $key
1646
   *
1647
   * @return self (Mutable) Return this Arrayy object, with the prepended value.
1648
   */
1649
  public function prepend($value, $key = null)
1650
  {
1651 16
    if ($key === null) {
1652
      array_unshift($this->array, $value);
1653 16
    } else {
1654
      /** @noinspection AdditionOperationOnArraysInspection */
1655
      $this->array = array($key => $value) + $this->array;
1656
    }
1657 16
1658 6
    return $this;
1659 6
  }
1660
1661 6
  /**
1662
   * Push one or more values onto the end of array at once.
1663
   *
1664 11
   * @return self (Mutable) Return this Arrayy object, with pushed elements to the end of array.
1665
   */
1666 11 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...
1667
  {
1668
    if (func_num_args()) {
1669
      $args = array_merge(array(&$this->array), func_get_args());
1670
      call_user_func_array('array_push', $args);
1671
    }
1672
1673
    return $this;
1674
  }
1675
1676 17
  /**
1677
   * Get a random value from the current array.
1678 17
   *
1679
   * @param null|int $number how many values you will take?
1680
   *
1681
   * @return Arrayy (Immutable)
1682 17
   */
1683 14
  public function randomImmutable($number = null)
1684
  {
1685 14
    if ($this->count() === 0) {
1686
      return static::create();
1687
    }
1688 5
1689 5 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...
1690
      $arrayRandValue = (array)$this->array[array_rand($this->array)];
1691 5
1692
      return static::create($arrayRandValue);
1693
    }
1694
1695
    $arrayTmp = $this->array;
1696
    shuffle($arrayTmp);
1697
1698
    return self::create($arrayTmp)->firstsImmutable($number);
1699
  }
1700
1701
  /**
1702 4
   * Pick a random key/index from the keys of this array.
1703
   *
1704 4
   *
1705
   * @return mixed get a key/index or null if there wasn't a key/index
1706 4
   *
1707
   * @throws \RangeException If array is empty
1708
   */
1709
  public function randomKey()
1710 4
  {
1711
    $result = $this->randomKeys(1);
1712
1713
    if (!isset($result[0])) {
1714
      $result[0] = null;
1715
    }
1716
1717
    return $result[0];
1718
  }
1719
1720
  /**
1721
   * Pick a given number of random keys/indexes out of this array.
1722 14
   *
1723
   * @param int $number The number of keys/indexes (should be <= $this->count())
1724 14
   *
1725 14
   * @return Arrayy (Immutable)
1726
   *
1727 14
   * @throws \RangeException If array is empty
1728 3
   */
1729
  public function randomKeys($number)
1730 3
  {
1731
    $number = (int)$number;
1732
    $count = $this->count();
1733
1734
    if ($number === 0 || $number > $count) {
1735
      throw new \RangeException(
1736
          sprintf(
1737 11
              'Number of requested keys (%s) must be equal or lower than number of elements in this array (%s)',
1738
              $number,
1739 11
              $count
1740
          )
1741
      );
1742
    }
1743
1744
    $result = (array)array_rand($this->array, $number);
1745
1746
    return static::create($result);
1747 4
  }
1748
1749 4
  /**
1750
   * Get a random value from the current array.
1751 4
   *
1752
   * @param null|int $number how many values you will take?
1753
   *
1754
   * @return Arrayy (Mutable)
1755 4
   */
1756
  public function randomMutable($number = null)
1757
  {
1758
    if ($this->count() === 0) {
1759
      return static::create();
1760
    }
1761
1762 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...
1763
      $arrayRandValue = (array)$this->array[array_rand($this->array)];
1764
      $this->array = $arrayRandValue;
1765 7
1766
      return $this;
1767 7
    }
1768
1769 7
    shuffle($this->array);
1770
1771
    return $this->firstsMutable($number);
1772
  }
1773
1774
  /**
1775
   * Pick a random value from the values of this array.
1776
   *
1777
   * @return mixed get a random value or null if there wasn't a value
1778
   */
1779
  public function randomValue()
1780
  {
1781
    $result = $this->randomImmutable();
1782 9
1783
    if (!isset($result[0])) {
1784 9
      $result[0] = null;
1785 9
    }
1786 9
1787 9
    return $result[0];
1788 1
  }
1789
1790
  /**
1791
   * Pick a given number of random values out of this array.
1792
   *
1793 9
   * @param int $number
1794
   *
1795
   * @return Arrayy (Mutable)
1796
   */
1797
  public function randomValues($number)
1798
  {
1799
    $number = (int)$number;
1800
1801
    return $this->randomMutable($number);
1802
  }
1803
1804 3
  /**
1805
   * Get a random value from an array, with the ability to skew the results.
1806 3
   *
1807
   * Example: randomWeighted(['foo' => 1, 'bar' => 2]) has a 66% chance of returning bar.
1808 3
   *
1809
   * @param array    $array
1810
   * @param null|int $number how many values you will take?
1811 3
   *
1812
   * @return Arrayy (Immutable)
1813
   */
1814 3
  public function randomWeighted(array $array, $number = null)
1815
  {
1816
    $options = array();
1817
    foreach ($array as $option => $weight) {
1818
      if ($this->searchIndex($option) !== false) {
1819
        for ($i = 0; $i < $weight; ++$i) {
1820
          $options[] = $option;
1821
        }
1822 9
      }
1823
    }
1824 9
1825
    return $this->mergeAppendKeepIndex($options)->randomImmutable($number);
1826 9
  }
1827
1828
  /**
1829
   * Reduce the current array via callable e.g. anonymous-function.
1830
   *
1831
   * @param mixed $callable
1832
   * @param array $init
1833
   *
1834
   * @return Arrayy (Immutable)
1835
   */
1836 1
  public function reduce($callable, array $init = array())
1837
  {
1838 1
    $result = array_reduce($this->array, $callable, $init);
1839
1840 1
    if ($result === null) {
1841 1
      $this->array = array();
1842 1
    } else {
1843
      $this->array = (array)$result;
1844
    }
1845
1846 1
    return static::create($this->array);
1847
  }
1848
1849
  /**
1850
   * Create a numerically re-indexed Arrayy object.
1851
   *
1852
   * @return self (Mutable) Return this Arrayy object, with re-indexed array-elements.
1853
   */
1854
  public function reindex()
1855
  {
1856 18
    $this->array = array_values($this->array);
1857
1858
    return $this;
1859 18
  }
1860
1861
  /**
1862
   * Return all items that fail the truth test.
1863
   *
1864
   * @param \Closure $closure
1865
   *
1866
   * @return Arrayy (Immutable)
1867 18
   */
1868 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...
1869 18
  {
1870
    $filtered = array();
1871
1872
    foreach ($this->array as $key => $value) {
1873
      if (!$closure($value, $key)) {
1874
        $filtered[$key] = $value;
1875
      }
1876
    }
1877 7
1878
    return static::create($filtered);
1879 7
  }
1880
1881 7
  /**
1882
   * Remove a value from the current array (optional using dot-notation).
1883
   *
1884
   * @param mixed $key
1885
   *
1886
   * @return Arrayy (Immutable)
1887
   */
1888
  public function remove($key)
1889 7
  {
1890
    // Recursive call
1891 7
    if (is_array($key)) {
1892
      foreach ($key as $k) {
1893 7
        $this->internalRemove($k);
1894
      }
1895
1896
      return static::create($this->array);
1897
    }
1898
1899
    $this->internalRemove($key);
1900
1901
    return static::create($this->array);
1902
  }
1903 7
1904
  /**
1905 7
   * Remove the first value from the current array.
1906 7
   *
1907 6
   * @return Arrayy (Immutable)
1908 6
   */
1909
  public function removeFirst()
1910
  {
1911 6
    array_shift($this->array);
1912
1913
    return static::create($this->array);
1914
  }
1915 7
1916 7
  /**
1917
   * Remove the last value from the current array.
1918
   *
1919 7
   * @return Arrayy (Immutable)
1920
   */
1921
  public function removeLast()
1922
  {
1923
    array_pop($this->array);
1924
1925
    return static::create($this->array);
1926
  }
1927
1928
  /**
1929
   * Removes a particular value from an array (numeric or associative).
1930
   *
1931 2
   * @param mixed $value
1932
   *
1933 2
   * @return Arrayy (Immutable)
1934
   */
1935 2
  public function removeValue($value)
1936
  {
1937
    $isNumericArray = true;
1938
    foreach ($this->array as $key => $item) {
1939
      if ($item === $value) {
1940
        if (!is_int($key)) {
1941
          $isNumericArray = false;
1942
        }
1943
        unset($this->array[$key]);
1944
      }
1945 2
    }
1946
1947 2
    if ($isNumericArray) {
1948
      $this->array = array_values($this->array);
1949 2
    }
1950
1951
    return static::create($this->array);
1952
  }
1953
1954
  /**
1955
   * Replace a key with a new key/value pair.
1956
   *
1957
   * @param $replace
1958
   * @param $key
1959 2
   * @param $value
1960
   *
1961 2
   * @return Arrayy (Immutable)
1962
   */
1963 2
  public function replace($replace, $key, $value)
1964
  {
1965
    $this->remove($replace);
1966
1967
    return $this->set($key, $value);
1968
  }
1969
1970
  /**
1971
   * Create an array using the current array as values and the other array as keys.
1972
   *
1973 1
   * @param array $keys Keys array
1974
   *
1975 1
   * @return Arrayy (Immutable) Arrayy object with keys from the other array.
1976 1
   */
1977
  public function replaceAllKeys(array $keys)
1978 1
  {
1979
    $result = array_combine($keys, $this->array);
1980
1981
    return static::create($result);
1982
  }
1983
1984
  /**
1985
   * Create an array using the current array as keys and the other array as values.
1986
   *
1987
   * @param array $array Values array
1988
   *
1989 3
   * @return Arrayy (Immutable) Arrayy object with values from the other array.
1990
   */
1991 3
  public function replaceAllValues(array $array)
1992 3
  {
1993
    $result = array_combine($this->array, $array);
1994 3
1995 3
    return static::create($result);
1996
  }
1997
1998 3
  /**
1999
   * Replace the keys in an array with another set.
2000
   *
2001
   * @param array $keys An array of keys matching the array's size
2002
   *
2003
   * @return Arrayy (Immutable)
2004
   */
2005
  public function replaceKeys(array $keys)
2006
  {
2007
    $values = array_values($this->array);
2008
    $result = array_combine($keys, $values);
2009 1
2010
    return static::create($result);
2011 1
  }
2012
2013 1
  /**
2014 1
   * Replace the first matched value in an array.
2015
   *
2016
   * @param mixed $search
2017 1
   * @param mixed $replacement
2018
   *
2019
   * @return Arrayy (Immutable)
2020
   */
2021
  public function replaceOneValue($search, $replacement = '')
2022
  {
2023
    $array = $this->array;
2024
    $key = array_search($search, $array, true);
2025
2026
    if ($key !== false) {
2027 15
      $array[$key] = $replacement;
2028
    }
2029 15
2030
    return static::create($array);
2031 15
  }
2032
2033
  /**
2034
   * Replace values in the current array.
2035
   *
2036
   * @param string $search      The string to replace.
2037
   * @param string $replacement What to replace it with.
2038
   *
2039 7
   * @return Arrayy (Immutable)
2040
   */
2041 7
  public function replaceValues($search, $replacement = '')
2042
  {
2043 7
    $array = $this->each(
2044
        function ($value) use ($search, $replacement) {
2045
          return UTF8::str_replace($search, $replacement, $value);
2046
        }
2047
    );
2048
2049
    return $array;
2050
  }
2051
2052
  /**
2053 20
   * Get the last elements from index $from until the end of this array.
2054
   *
2055 20
   * @param int $from
2056
   *
2057
   * @return Arrayy (Immutable)
2058
   */
2059
  public function rest($from = 1)
2060
  {
2061
    $result = array_splice($this->array, $from);
2062
2063
    return static::create($result);
2064
  }
2065 7
2066
  /**
2067
   * Return the array in the reverse order.
2068 7
   *
2069
   * @return self (Mutable) Return this Arrayy object.
2070 7
   */
2071 7
  public function reverse()
2072
  {
2073 7
    $this->array = array_reverse($this->array);
2074 5
2075
    return $this;
2076
  }
2077
2078 7
  /**
2079
   * Search for the first index of the current array via $value.
2080
   *
2081
   * @param mixed $value
2082
   *
2083
   * @return mixed
2084
   */
2085
  public function searchIndex($value)
2086
  {
2087
    return array_search($value, $this->array, true);
2088
  }
2089 17
2090
  /**
2091 17
   * Search for the value of the current array via $index.
2092
   *
2093 17
   * @param mixed $index
2094
   *
2095
   * @return Arrayy (Immutable) will return a empty Arrayy if the value wasn't found
2096
   */
2097
  public function searchValue($index)
2098
  {
2099
    // init
2100
    $return = array();
2101
2102
    if (null !== $index) {
2103
      $keyExists = isset($this->array[$index]);
2104
2105
      if ($keyExists !== false) {
2106 10
        $return = array($this->array[$index]);
2107
      }
2108
    }
2109 10
2110 5
    return static::create($return);
2111
  }
2112
2113 10
  /**
2114
   * Set a value for the current array (optional using dot-notation).
2115
   *
2116
   * @param string $key   The key to set
2117
   * @param mixed  $value Its value
2118
   *
2119
   * @return Arrayy (Immutable)
2120
   */
2121 4
  public function set($key, $value)
2122
  {
2123 4
    $this->internalSet($key, $value);
2124
2125
    return static::create($this->array);
2126
  }
2127
2128
  /**
2129
   * Get a value from a array and set it if it was not.
2130
   *
2131 1
   * WARNING: this method only set the value, if the $key is not already set
2132
   *
2133 1
   * @param string $key      The key
2134
   * @param mixed  $fallback The default value to set if it isn't
2135 1
   *
2136
   * @return mixed (Mutable)
2137 1
   */
2138
  public function setAndGet($key, $fallback = null)
2139
  {
2140
    // If the key doesn't exist, set it
2141
    if (!$this->has($key)) {
2142
      $this->array = $this->set($key, $fallback)->getArray();
2143
    }
2144
2145 110
    return $this->get($key);
2146
  }
2147 110
2148
  /**
2149
   * Shifts a specified value off the beginning of array.
2150
   *
2151
   * @return mixed A shifted element from the current array.
2152
   */
2153
  public function shift()
2154
  {
2155
    return array_shift($this->array);
2156
  }
2157
2158
  /**
2159 4
   * Shuffle the current array.
2160
   *
2161 4
   * @return Arrayy (Immutable)
2162
   */
2163 4
  public function shuffle()
2164
  {
2165
    $array = $this->array;
2166
2167
    shuffle($array);
2168
2169
    return static::create($array);
2170
  }
2171
2172
  /**
2173
   * Get the size of an array.
2174
   *
2175 19
   * @return int
2176
   */
2177 19
  public function size()
2178
  {
2179 19
    return count($this->array);
2180
  }
2181
2182
  /**
2183
   * Extract a slice of the array.
2184
   *
2185
   * @param int      $offset       Slice begin index
2186
   * @param int|null $length       Length of the slice
2187
   * @param bool     $preserveKeys Whether array keys are preserved or no
2188
   *
2189
   * @return static A slice of the original array with length $length
2190
   */
2191
  public function slice($offset, $length = null, $preserveKeys = false)
2192
  {
2193 18
    $result = array_slice($this->array, $offset, $length, $preserveKeys);
2194
2195 18
    return static::create($result);
2196
  }
2197 18
2198
  /**
2199
   * Sort the current array and optional you can keep the keys.
2200
   *
2201
   * @param integer $direction use SORT_ASC or SORT_DESC
2202
   * @param integer $strategy
2203
   * @param bool    $keepKeys
2204
   *
2205
   * @return self (Mutable) Return this Arrayy object.
2206
   */
2207
  public function sort($direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2208 1
  {
2209
    $this->sorting($this->array, $direction, $strategy, $keepKeys);
2210 1
2211
    return $this;
2212
  }
2213
2214
  /**
2215
   * Sort the current array by key.
2216
   *
2217
   * @link http://php.net/manual/en/function.ksort.php
2218
   * @link http://php.net/manual/en/function.krsort.php
2219
   *
2220
   * @param int|string $direction use SORT_ASC or SORT_DESC
2221 1
   * @param int        $strategy  use e.g.: SORT_REGULAR or SORT_NATURAL
2222
   *
2223 1
   * @return self (Mutable) Return this Arrayy object.
2224
   */
2225
  public function sortKeys($direction = SORT_ASC, $strategy = SORT_REGULAR)
2226
  {
2227
    $this->sorterKeys($this->array, $direction, $strategy);
2228
2229
    return $this;
2230
  }
2231
2232
  /**
2233
   * Sort the current array by value.
2234
   *
2235
   * @param int $direction use SORT_ASC or SORT_DESC
2236
   * @param int $strategy  use e.g.: SORT_REGULAR or SORT_NATURAL
2237
   *
2238 1
   * @return Arrayy (Immutable)
2239
   */
2240 1
  public function sortValueKeepIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2241 1
  {
2242
    return $this->sort($direction, $strategy, true);
2243
  }
2244 1
2245 1
  /**
2246
   * Sort the current array by value.
2247 1
   *
2248 1
   * @param int $direction use SORT_ASC or SORT_DESC
2249
   * @param int $strategy  use e.g.: SORT_REGULAR or SORT_NATURAL
2250 1
   *
2251 1
   * @return Arrayy (Immutable)
2252
   */
2253
  public function sortValueNewIndex($direction = SORT_ASC, $strategy = SORT_REGULAR)
2254 1
  {
2255
    return $this->sort($direction, $strategy, false);
2256 1
  }
2257
2258
  /**
2259
   * Sort a array by value, by a closure or by a property.
2260 1
   *
2261
   * - If the sorter is null, the array is sorted naturally.
2262 1
   * - Associative (string) keys will be maintained, but numeric keys will be re-indexed.
2263
   *
2264
   * @param null       $sorter
2265
   * @param string|int $direction
2266
   * @param int        $strategy
2267
   *
2268
   * @return Arrayy (Immutable)
2269
   */
2270
  public function sorter($sorter = null, $direction = SORT_ASC, $strategy = SORT_REGULAR)
2271
  {
2272 18
    $array = (array)$this->array;
2273
    $direction = $this->getDirection($direction);
2274 18
2275
    // Transform all values into their results.
2276
    if ($sorter) {
2277 18
      $arrayy = new self($array);
2278 18
2279 6
      $that = $this;
2280 6
      $results = $arrayy->each(
2281 13
          function ($value) use ($sorter, $that) {
2282 13
            return is_callable($sorter) ? $sorter($value) : $that->get($sorter, null, $value);
2283
          }
2284 13
      );
2285
2286 18
      $results = $results->getArray();
2287
    } else {
2288
      $results = $array;
2289
    }
2290
2291
    // Sort by the results and replace by original values
2292
    array_multisort($results, $direction, $strategy, $array);
2293
2294 19
    return static::create($array);
2295
  }
2296 19
2297
  /**
2298 19
   * sorting keys
2299 19
   *
2300
   * @param array $elements
2301
   * @param int   $direction
2302
   * @param int   $strategy
2303 19
   */
2304 19
  protected function sorterKeys(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR)
2305 9
  {
2306 5
    $direction = $this->getDirection($direction);
2307
2308 4
    switch ($direction) {
2309
      case 'desc':
2310 9
      case SORT_DESC:
2311 10
        krsort($elements, $strategy);
2312 10
        break;
2313
      case 'asc':
2314 10
      case SORT_ASC:
2315 4
      default:
2316
        ksort($elements, $strategy);
2317 6
    }
2318
  }
2319
2320 19
  /**
2321
   * @param array      &$elements
2322
   * @param int|string $direction
2323
   * @param int        $strategy
2324
   * @param bool       $keepKeys
2325
   */
2326
  protected function sorting(array &$elements, $direction = SORT_ASC, $strategy = SORT_REGULAR, $keepKeys = false)
2327
  {
2328
    $direction = $this->getDirection($direction);
2329
2330 1
    if (!$strategy) {
2331
      $strategy = SORT_REGULAR;
2332 1
    }
2333 1
2334
    switch ($direction) {
2335 1
      case 'desc':
2336 1
      case SORT_DESC:
2337 1
        if ($keepKeys) {
2338
          arsort($elements, $strategy);
2339
        } else {
2340 1
          rsort($elements, $strategy);
2341
        }
2342
        break;
2343
      case 'asc':
2344
      case SORT_ASC:
2345
      default:
2346 153
        if ($keepKeys) {
2347
          asort($elements, $strategy);
2348 153
        } else {
2349
          sort($elements, $strategy);
2350
        }
2351
    }
2352
  }
2353
2354
  /**
2355
   * Split an array in the given amount of pieces.
2356
   *
2357
   * @param int  $numberOfPieces
2358 5
   * @param bool $keepKeys
2359
   *
2360 5
   * @return Arrayy (Immutable)
2361
   */
2362
  public function split($numberOfPieces = 2, $keepKeys = false)
2363
  {
2364
    if (count($this->array) === 0) {
2365
      $result = array();
2366
    } else {
2367
      $numberOfPieces = (int)$numberOfPieces;
2368
      $splitSize = ceil(count($this->array) / $numberOfPieces);
2369
      $result = array_chunk($this->array, $splitSize, $keepKeys);
2370 15
    }
2371
2372 15
    return static::create($result);
2373
  }
2374
2375
  /**
2376
   * Stripe all empty items.
2377
   *
2378
   * @return Arrayy (Immutable)
2379
   */
2380 8
  public function stripEmpty()
2381
  {
2382 8
    return $this->filter(
2383 8
        function ($item) {
2384 8
          if (null === $item) {
2385 7
            return false;
2386 7
          }
2387
2388
          return (bool)trim($item);
2389 7
        }
2390 8
    );
2391 8
  }
2392
2393
  /**
2394 8
   * Swap two values between positions by key.
2395
   *
2396
   * @param string|int $swapA an key in the array
2397 8
   * @param string|int $swapB an key in the array
2398
   *
2399
   * @return Arrayy (Immutable)
2400 8
   */
2401
  public function swap($swapA, $swapB)
2402
  {
2403
    $array = $this->array;
2404
2405
    list($array[$swapA], $array[$swapB]) = [$array[$swapB], $array[$swapA]];
2406
2407
    return static::create($array);
2408 4
  }
2409
2410 4
  /**
2411 4
   * alias: for "Arrayy->getArray()"
2412 4
   */
2413
  public function toArray()
2414
  {
2415 4
    return $this->getArray();
2416
  }
2417
2418
  /**
2419
   * Convert the current array to JSON.
2420
   *
2421
   * @param null $options e.g. JSON_PRETTY_PRINT
2422
   *
2423 1
   * @return string
2424
   */
2425 1
  public function toJson($options = null)
2426
  {
2427 1
    return UTF8::json_encode($this->array, $options);
2428
  }
2429
2430
  /**
2431
   * Implodes array to a string with specified separator.
2432
   *
2433
   * @param string $separator The element's separator
2434
   *
2435
   * @return string The string representation of array, separated by ","
2436
   */
2437
  public function toString($separator = ',')
2438 9
  {
2439
    return $this->implode($separator);
2440 9
  }
2441 4
2442
  /**
2443 5
   * Return a duplicate free copy of the current array.
2444
   *
2445
   * @return Arrayy (Mutable)
2446 9
   */
2447
  public function unique()
2448
  {
2449
    $this->array = array_reduce(
0 ignored issues
show
Documentation Bug introduced by
It seems like array_reduce($this->arra...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...
2450
        $this->array,
2451
        function ($resultArray, $value) {
2452
          if (in_array($value, $resultArray, true) === false) {
2453
            $resultArray[] = $value;
2454
          }
2455
2456
          return $resultArray;
2457
        },
2458
        array()
2459
    );
2460
2461
    if ($this->array === null) {
2462
      $this->array = array();
2463
    } else {
2464
      $this->array = (array)$this->array;
2465
    }
2466
2467
    return $this;
2468
  }
2469
2470
  /**
2471
   * Prepends one or more values to the beginning of array at once.
2472
   *
2473
   * @return self (Mutable) Return this Arrayy object, with prepended elements to the beginning of array.
2474
   */
2475 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...
2476
  {
2477
    if (func_num_args()) {
2478
      $args = array_merge(array(&$this->array), func_get_args());
2479
      call_user_func_array('array_unshift', $args);
2480
    }
2481
2482
    return $this;
2483
  }
2484
2485
  /**
2486
   * Get all values from a array.
2487
   *
2488
   * @return Arrayy (Immutable)
2489
   */
2490
  public function values()
2491
  {
2492
    return static::create(array_values((array)$this->array));
2493
  }
2494
2495
  /**
2496
   * Apply the given function to every element in the array, discarding the results.
2497
   *
2498
   * @param callable $callable
2499
   * @param bool     $recursive Whether array will be walked recursively or no
2500
   *
2501
   * @return self (Mutable) Return this Arrayy object, with modified elements
2502
   */
2503
  public function walk($callable, $recursive = false)
2504
  {
2505
    if (true === $recursive) {
2506
      array_walk_recursive($this->array, $callable);
2507
    } else {
2508
      array_walk($this->array, $callable);
2509
    }
2510
2511
    return $this;
2512
  }
2513
2514
2515
}
2516