Completed
Push — master ( a7e59d...f4a839 )
by Lars
02:09
created

Arrayy   D

Complexity

Total Complexity 331

Size/Duplication

Total Lines 3030
Duplicated Lines 4.92 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 91.09%

Importance

Changes 0
Metric Value
dl 149
loc 3030
ccs 849
cts 932
cp 0.9109
rs 4.4102
c 0
b 0
f 0
wmc 331
lcom 1
cbo 2

163 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A __get() 0 10 2
A __invoke() 0 12 3
A __isset() 0 4 1
A __set() 0 4 1
A __toString() 0 4 1
A __unset() 0 4 1
A add() 0 4 1
A append() 0 6 1
A asort() 0 4 1
A count() 0 4 1
A exchangeArray() 0 6 1
A getArrayCopy() 0 4 1
A getIterator() 0 6 1
A getIteratorClass() 0 4 1
A ksort() 0 4 1
A natcasesort() 0 4 1
A natsort() 0 4 1
C offsetExists() 0 44 7
A offsetGet() 0 6 2
A offsetSet() 0 8 2
B offsetUnset() 0 26 4
A serialize() 0 4 1
A setIteratorClass() 0 19 4
A uasort() 0 6 2
A uksort() 0 6 2
A unserialize() 0 6 1
A at() 10 10 2
A average() 0 14 3
B callAtPath() 0 23 4
A changeKeyCase() 0 4 1
A changeSeparator() 0 6 1
A chunk() 0 6 1
A clean() 0 8 1
A clear() 0 6 1
A contains() 0 4 1
A containsCaseInsensitive() 0 14 1
A containsKey() 0 4 1
A containsKeys() 0 4 1
A containsValue() 0 4 1
A containsValues() 0 4 1
A create() 0 4 1
A createByReference() 0 8 1
A createFromJson() 0 6 1
A createFromObject() 0 10 2
B createFromString() 0 26 4
A createWithRange() 0 4 1
A customSortKeys() 0 6 1
A customSortValues() 0 6 1
A diff() 0 6 1
C diffRecursive() 0 33 8
A diffReverse() 0 6 1
A divide() 0 9 1
A each() 10 10 2
A exists() 0 12 3
C fallbackForArray() 0 42 13
A filter() 0 10 2
A filterBy() 0 65 3
A find() 0 10 3
A findBy() 0 4 1
A first() 0 11 2
A firstsImmutable() 0 13 2
A firstsMutable() 0 11 2
A flip() 0 6 1
C get() 0 44 11
A getArray() 0 6 1
A getColumn() 0 6 1
B getDirection() 0 22 5
A getKeys() 0 4 1
A getRandom() 0 4 1
A getRandomKey() 0 4 1
A getRandomKeys() 0 4 1
A getRandomValue() 0 4 1
A getRandomValues() 0 4 1
C group() 0 34 7
A has() 0 7 1
A implode() 0 4 1
A indexBy() 0 12 3
A indexOf() 0 4 1
A initial() 0 6 1
A internalGetArray() 0 8 3
A internalRemove() 0 21 3
B internalSet() 0 28 5
A intersection() 0 4 1
A intersects() 0 4 1
A invoke() 0 16 3
A isAssoc() 0 14 4
A isEmpty() 0 4 1
A isEqual() 0 4 1
A isMultiArray() 0 4 1
A isNumeric() 0 14 4
A isSequential() 0 4 1
A jsonSerialize() 0 4 1
A keys() 0 4 1
A last() 0 4 1
B lastsImmutable() 0 23 4
B lastsMutable() 0 23 4
A length() 0 4 1
A map() 0 6 1
A matches() 19 19 4
A matchesAny() 19 19 4
A max() 0 8 2
A mergeAppendKeepIndex() 10 10 2
A mergeAppendNewIndex() 10 10 2
A mergePrependKeepIndex() 10 10 2
A mergePrependNewIndex() 10 10 2
A min() 0 8 2
B moveElement() 0 27 5
A only() 0 6 1
A pad() 0 6 1
A pop() 0 4 1
A prepend() 0 11 2
A push() 9 9 2
A randomImmutable() 5 17 3
A randomKey() 0 10 2
A randomKeys() 0 19 3
A randomMutable() 6 17 3
A randomValue() 0 10 2
A randomValues() 0 6 1
A randomWeighted() 0 13 4
A reduce() 0 12 2
A reindex() 0 6 1
A reject() 12 12 3
A remove() 0 15 3
A removeFirst() 0 7 1
A removeLast() 0 7 1
B removeValue() 0 18 5
A repeat() 0 8 2
A replace() 0 6 1
A replaceAllKeys() 0 6 1
A replaceAllValues() 0 6 1
A replaceKeys() 0 7 1
A replaceOneValue() 0 11 2
A replaceValues() 0 10 1
A rest() 0 6 1
A reverse() 0 6 1
A searchIndex() 0 4 1
A searchValue() 0 21 4
A set() 0 6 1
A setAndGet() 0 9 2
A shift() 0 4 1
A shuffle() 0 8 1
A size() 0 4 1
A slice() 0 6 1
A sort() 0 6 1
A sortKeys() 0 6 1
A sortValueKeepIndex() 0 4 1
A sortValueNewIndex() 0 4 1
B sorter() 0 26 3
B sorterKeys() 0 15 5
C sorting() 0 27 8
A split() 0 14 2
A stripEmpty() 0 12 2
A swap() 0 8 1
A toArray() 0 4 1
A toJson() 0 4 1
A toString() 0 4 1
A unique() 5 22 3
B uniqueKeepIndex() 5 25 3
A uniqueNewIndex() 0 4 1
A unshift() 9 9 2
A values() 0 4 1
A walk() 0 10 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Arrayy often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Arrayy, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Arrayy;
4
5
use voku\helper\UTF8;
6
7
/** @noinspection ClassReImplementsParentInterfaceInspection */
8
9
/**
10
 * Methods to manage arrays.
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
class Arrayy extends \ArrayObject implements \JsonSerializable, \IteratorAggregate, \ArrayAccess, \Serializable, \Countable
16
{
17
  /**
18
   * @var array
19
   */
20
  protected $array = array();
21
22
  /**
23
   * @var string
24
   */
25
  protected $iteratorClass;
26
27
  /**
28
   * @var string
29
   */
30
  protected $pathSeparator = '.';
31 759
32
  /** @noinspection MagicMethodsValidityInspection */
33 759
  /**
34
   * Initializes
35 757
   *
36 757
   * @param array  $array
37
   * @param string $iteratorClass
38
   */
39
  public function __construct($array = array(), $iteratorClass = '\\Arrayy\\ArrayyIterator')
40
  {
41
    $array = $this->fallbackForArray($array);
42
    $this->array = $array;
43
44
    $this->setIteratorClass($iteratorClass);
45 1
  }
46
47 1
  /**
48
   * Get a value by key.
49 1
   *
50
   * @param $key
51
   *
52
   * @return mixed <p>Get a Value from the current array.</p>
53 1
   */
54
  public function &__get($key)
55
  {
56
    $return = $this->get($key);
57
58
    if (is_array($return)) {
59
      return static::create($return);
60
    }
61
62
    return $return;
63
  }
64
65
  /**
66
   * Call object as function.
67
   *
68
   * @param mixed $key
69
   *
70
   * @return mixed
71
   */
72
  public function __invoke($key = null)
73
  {
74
    if ($key !== null) {
75
      if (isset($this->array[$key])) {
76
        return $this->array[$key];
77
      }
78
79
      return false;
80
    }
81
82
    return (array)$this->array;
83
  }
84
85
  /**
86
   * Whether or not an element exists by key.
87
   *
88
   * @param mixed $key
89
   *
90
   * @return bool <p>True is the key/index exists, otherwise false.</p>
91
   */
92
  public function __isset($key)
93
  {
94 2
    return $this->offsetExists($key);
95
  }
96 2
97 2
  /**
98
   * Assigns a value to the specified element.
99
   *
100
   * @param mixed $key
101
   * @param mixed $value
102
   */
103
  public function __set($key, $value)
104 16
  {
105
    $this->internalSet($key, $value);
106 16
  }
107
108
  /**
109
   * magic to string
110
   *
111
   * @return string
112
   */
113
  public function __toString()
114
  {
115
    return $this->toString();
116
  }
117
118
  /**
119
   * Unset element by key.
120
   *
121
   * @param mixed $key
122
   */
123
  public function __unset($key)
124
  {
125
    $this->internalRemove($key);
126
  }
127
128 1
  /**
129
   * alias: for "Arrayy->append()"
130 1
   *
131
   * @see Arrayy::append()
132
   *
133
   * @param mixed $value
134
   *
135
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
136
   */
137
  public function add($value)
138
  {
139
    return $this->append($value);
140 9
  }
141
142 9
  /**
143
   * Append a value to the current array.
144 9
   *
145
   * @param mixed $value
146
   *
147
   * @return static <p>(Mutable) Return this Arrayy object, with the appended values.</p>
148
   */
149
  public function append($value)
150
  {
151
    $this->array[] = $value;
152
153
    return $this;
154
  }
155
156 93
  /**
157
   * Sort the entries by value
158 93
   *
159
   * @return void
160
   */
161
  public function asort()
162
  {
163
    asort($this->array);
164
  }
165
166 19
  /**
167
   * Count the values from the current array.
168 19
   *
169
   * alias: for "Arrayy->size()"
170
   *
171
   * @see Arrayy::size()
172
   *
173
   * @return int
174
   */
175
  public function count()
176
  {
177
    return $this->size();
178 38
  }
179
180 38
  /**
181 4
   * Exchange the array for another one.
182
   *
183
   * @param  array|Arrayy $data
184
   *
185 34
   * @return array
186 1
   */
187 1
  public function exchangeArray($data)
188
  {
189 34
    $this->array = $this->fallbackForArray($data);
190
191
    return $this->array;
192
  }
193 34
194
  /**
195
   * Creates a copy of the ArrayyObject.
196 11
   *
197 11
   * @return array
198 11
   */
199 34
  public function getArrayCopy()
200 32
  {
201
    return $this->array;
202
  }
203 2
204
  /**
205 2
   * Returns a new ArrayyIterator, thus implementing the IteratorAggregate interface.
206
   *
207 2
   * @return ArrayyIterator <p>An iterator for the values in the array.</p>
208 2
   */
209 2
  public function getIterator()
210 2
  {
211
    $iterator = $this->getIteratorClass();
212 2
213 2
    return new $iterator($this->array);
214
  }
215 2
216 2
  /**
217 2
   * Gets the iterator classname for the ArrayObject.
218 2
   *
219
   * @return string
220 2
   */
221
  public function getIteratorClass()
222
  {
223
    return $this->iteratorClass;
224
  }
225
226
  /**
227
   * Sort the entries by key
228
   *
229
   * @return void
230 24
   */
231
  public function ksort()
232 24
  {
233
    ksort($this->array);
234
  }
235
236
  /**
237
   * Sort an array using a case insensitive "natural order" algorithm
238
   *
239
   * @return void
240
   */
241 15
  public function natcasesort()
242
  {
243 15
    natcasesort($this->array);
244 4
  }
245 4
246 11
  /**
247
   * Sort entries using a "natural order" algorithm
248 15
   *
249
   * @return void
250
   */
251
  public function natsort()
252
  {
253
    natsort($this->array);
254
  }
255 6
256
  /**
257 6
   * Whether or not an offset exists.
258 1
   *
259
   * @param int|float|string $offset
260
   *
261 5
   * @return bool
262 3
   */
263
  public function offsetExists($offset)
264 3
  {
265
    if ($this->isEmpty()) {
266
      return false;
267 2
    }
268
269 1
    // php cast "bool"-index into "int"-index
270 1
    if ((bool)$offset === $offset) {
271
      $offset = (int)$offset;
272 1
    }
273 1
274
    $tmpReturn = \array_key_exists($offset, $this->array);
275 1
276 1
    if (
277 1
        $tmpReturn === true
278
        ||
279 1
        (
280 2
            $tmpReturn === false
281
            &&
282
            strpos((string)$offset, $this->pathSeparator) === false
283
        )
284
    ) {
285
      return $tmpReturn;
286
    }
287 2
288
    $offsetExists = false;
289 2
290
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
291
292
      $offsetExists = false;
293
      $explodedPath = explode($this->pathSeparator, (string)$offset);
294
      $lastOffset = \array_pop($explodedPath);
295
      $containerPath = implode($this->pathSeparator, $explodedPath);
296
297
      $this->callAtPath(
298
          $containerPath,
299 2
          function ($container) use ($lastOffset, &$offsetExists) {
300
            $offsetExists = \array_key_exists($lastOffset, $container);
301 2
          }
302
      );
303 2
    }
304
305
    return $offsetExists;
306
  }
307
308
  /**
309
   * Returns the value at specified offset.
310
   *
311
   * @param mixed $offset
312
   *
313 2
   * @return mixed <p>Will return null if the offset did not exists.</p>
314
   */
315 2
  public function &offsetGet($offset)
316
  {
317 2
    $return = $this->offsetExists($offset) ? $this->get($offset) : null;
318 2
319 2
    return $return;
320
  }
321 2
322
  /**
323
   * Assigns a value to the specified offset.
324
   *
325
   * @param mixed $offset
326
   * @param mixed $value
327
   */
328
  public function offsetSet($offset, $value)
329
  {
330
    if ($offset === null) {
331 10
      $this->array[] = $value;
332
    } else {
333 10
      $this->internalSet($offset, $value);
334
    }
335 10
  }
336 2
337
  /**
338
   * Unset an offset.
339 8
   *
340 3
   * @param mixed $offset
341 3
   */
342
  public function offsetUnset($offset)
343 8
  {
344
    if ($this->isEmpty()) {
345
      return;
346
    }
347
348
    if (\array_key_exists($offset, $this->array)) {
349
      unset($this->array[$offset]);
350
351 2
      return;
352
    }
353 2
354 2
    if (strpos((string)$offset, $this->pathSeparator) !== false) {
355 2
356
      $path = explode($this->pathSeparator, (string)$offset);
357 2
      $pathToUnset = \array_pop($path);
358 2
359
      $this->callAtPath(
360 2
          implode($this->pathSeparator, $path),
361
          function (&$offset) use ($pathToUnset) {
362
            unset($offset[$pathToUnset]);
363
          }
364 2
      );
365
366
    }
367
  }
368
369
  /**
370
   * Serialize the current "Arrayy"-object.
371 2
   *
372
   * @return string
373 2
   */
374
  public function serialize()
375
  {
376
    return parent::serialize();
377
  }
378
379
  /**
380
   * Sets the iterator classname for the current "Arrayy"-object.
381
   *
382
   * @param  string $class
383
   *
384
   * @return void
385
   *
386
   * @throws \InvalidArgumentException
387
   */
388
  public function setIteratorClass($class)
389
  {
390
    if (class_exists($class)) {
391
      $this->iteratorClass = $class;
392
393
      return;
394
    }
395
396
    if (strpos($class, '\\') === 0) {
397
      $class = '\\' . $class;
398
      if (class_exists($class)) {
399 4
        $this->iteratorClass = $class;
400
401 4
        return;
402
      }
403 4
    }
404
405
    throw new \InvalidArgumentException('The iterator class does not exist');
406
  }
407
408
  /**
409
   * Sort the entries with a user-defined comparison function and maintain key association
410
   *
411 8
   * @param  callable $function
412
   *
413 8
   * @return void
414
   */
415 7
  public function uasort($function)
416
  {
417 8
    if (is_callable($function)) {
418
      uasort($this->array, $function);
419
    }
420
  }
421
422
  /**
423
   * Sort the entries by keys using a user-defined comparison function
424
   *
425 4
   * @param  callable $function
426
   *
427 4
   * @return void
428
   */
429 4
  public function uksort($function)
430
  {
431
    if (is_callable($function)) {
432
      uksort($this->array, $function);
433
    }
434
  }
435
436
  /**
437
   * Unserialize an string and return this object.
438
   *
439 13
   * @param string $string
440
   *
441 13
   * @return static <p>(Mutable)</p>
442
   */
443
  public function unserialize($string)
444
  {
445
    parent::unserialize($string);
446
447
    return $this;
448
  }
449
450
  /**
451 13
   * Iterate over the current array and execute a callback for each loop.
452
   *
453 13
   * @param \Closure $closure
454 13
   *
455 13
   * @return static <p>(Immutable)</p>
456
   */
457 13 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...
458 13
  {
459 13
    $array = $this->array;
460 13
461 13
    foreach ($array as $key => $value) {
462
      $closure($value, $key);
463 13
    }
464
465
    return static::create($array);
466
  }
467
468
  /**
469
   * Returns the average value of the current array.
470
   *
471
   * @param int $decimals <p>The number of decimal-numbers to return.</p>
472
   *
473 4
   * @return int|double <p>The average value.</p>
474
   */
475 4
  public function average($decimals = 0)
476
  {
477
    $count = $this->count();
478
479
    if (!$count) {
480
      return 0;
481
    }
482
483
    if (!is_int($decimals)) {
484
      $decimals = 0;
485 1
    }
486
487 1
    return round(\array_sum($this->array) / $count, $decimals);
488
  }
489
490
  /**
491
   * @param mixed      $path
492
   * @param callable   $callable
493
   * @param null|array $currentOffset
494
   */
495
  protected function callAtPath($path, $callable, &$currentOffset = null)
496
  {
497
    if ($currentOffset === null) {
498
      $currentOffset = &$this->array;
499
    }
500
501
    $explodedPath = explode($this->pathSeparator, $path);
502
    $nextPath = \array_shift($explodedPath);
503
504
    if (!isset($currentOffset[$nextPath])) {
505
      return;
506
    }
507
508
    if (!empty($explodedPath)) {
509
      $this->callAtPath(
510
          implode($this->pathSeparator, $explodedPath),
511 1
          $callable,
512
          $currentOffset[$nextPath]
513 1
      );
514
    } else {
515
      $callable($currentOffset[$nextPath]);
516
    }
517
  }
518
519
  /**
520
   * Changes all keys in an array.
521
   *
522
   * @param int $case [optional] <p> Either <strong>CASE_UPPER</strong><br />
523 479
   *                  or <strong>CASE_LOWER</strong> (default)</p>
524
   *
525 479
   * @return static <p>(Immutable)</p>
526
   */
527
  public function changeKeyCase($case = CASE_LOWER)
528
  {
529
    return static::create(UTF8::array_change_key_case($this->array, $case));
0 ignored issues
show
Bug introduced by
The method array_change_key_case() does not seem to exist on object<voku\helper\UTF8>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
530
  }
531
532
  /**
533
   * Change the path separator of the array wrapper.
534
   *
535 1
   * By default, the separator is: "."
536
   *
537 1
   * @param string $separator <p>Separator to set.</p>
538 1
   *
539
   * @return static <p>Mutable</p>
540
   */
541 1
  public function changeSeparator($separator)
542
  {
543
    $this->pathSeparator = $separator;
544
545
    return $this;
546
  }
547
548
  /**
549
   * Create a chunked version of the current array.
550
   *
551
   * @param int  $size         <p>Size of each chunk.</p>
552
   * @param bool $preserveKeys <p>Whether array keys are preserved or no.</p>
553
   *
554
   * @return static <p>(Immutable) A new array of chunks from the original array.</p>
555
   */
556
  public function chunk($size, $preserveKeys = false)
557
  {
558
    $result = \array_chunk($this->array, $size, $preserveKeys);
559
560
    return static::create($result);
561
  }
562
563
  /**
564
   * Clean all falsy values from the current array.
565
   *
566
   * @return static <p>(Immutable)</p>
567
   */
568 5
  public function clean()
569
  {
570 5
    return $this->filter(
571
        function ($value) {
572 5
          return (bool)$value;
573
        }
574
    );
575
  }
576
577
  /**
578
   * WARNING!!! -> Clear the current array.
579
   *
580
   * @return static <p>(Mutable) Return this Arrayy object, with an empty array.</p>
581
   */
582 4
  public function clear()
583
  {
584 4
    $this->array = array();
585 4
586
    return $this;
587 3
  }
588 4
589
  /**
590 4
   * Check if an item is in the current array.
591
   *
592
   * @param string|int|float $value
593
   *
594
   * @return bool
595
   */
596
  public function contains($value)
597
  {
598
    return in_array($value, $this->array, true);
599
  }
600
601
  /**
602
   * Check if an (case-insensitive) string is in the current array.
603 8
   *
604
   * @param string $value
605 8
   *
606 1
   * @return bool
607
   */
608 1
  public function containsCaseInsensitive($value)
609 1
  {
610 1
    return in_array(
611
        UTF8::strtolower($value),
612 1
        \array_map(
613 7
            array(
614
                new UTF8(),
615
                'strtolower',
616
            ),
617 8
            $this->array
618
        ),
619
        true
620
    );
621 8
  }
622 8
623 8
  /**
624 8
   * Check if the given key/index exists in the array.
625 8
   *
626
   * @param string|int|float $key <p>key/index to search for</p>
627 8
   *
628
   * @return bool <p>Returns true if the given key/index exists in the array, false otherwise.</p>
629
   */
630
  public function containsKey($key)
631
  {
632
    return $this->offsetExists($key);
633
  }
634
635
  /**
636
   * Check if all given needles are present in the array as key/index.
637
   *
638
   * @param array $needles
639 1
   *
640
   * @return bool <p>Returns true if the given keys/indexes exists in the array, false otherwise.</p>
641 1
   */
642
  public function containsKeys(array $needles)
643
  {
644
    return count(\array_intersect($needles, $this->keys()->getArray())) === count($needles);
645
  }
646
647
  /**
648
   * alias: for "Arrayy->contains()"
649
   *
650
   * @see Arrayy::contains()
651
   *
652
   * @param string|int|float $value
653 5
   *
654
   * @return bool
655 5
   */
656
  public function containsValue($value)
657 5
  {
658
    return $this->contains($value);
659
  }
660
661
  /**
662
   * Check if all given needles are present in the array.
663
   *
664
   * @param array $needles
665
   *
666
   * @return bool <p>Returns true if the given values exists in the array, false otherwise.</p>
667
   */
668
  public function containsValues(array $needles)
669 4
  {
670
    return count(\array_intersect($needles, $this->array)) === count($needles);
671 4
  }
672
673 4
  /**
674
   * Creates an Arrayy object.
675
   *
676
   * @param array $array
677
   *
678
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
679
   */
680
  public static function create($array = array())
681
  {
682
    return new static($array);
683 12
  }
684
685 12
  /**
686
   * WARNING: Creates an Arrayy object by reference.
687 12
   *
688
   * @param array $array
689
   *
690
   * @return static <p>(Mutable) Return this Arrayy object.</p>
691
   */
692
  public function createByReference(&$array = array())
693
  {
694
    $array = $this->fallbackForArray($array);
695
696
    $this->array = &$array;
697
698 1
    return $this;
699
  }
700 1
701
  /**
702
   * Create an new Arrayy object via JSON.
703
   *
704 1
   * @param string $json
705 1
   *
706 1
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
707 1
   */
708 1
  public static function createFromJson($json)
709 1
  {
710
    $array = UTF8::json_decode($json, true);
711
712 1
    return static::create($array);
713 1
  }
714 1
715 1
  /**
716 1
   * Create an new instance filled with values from an object that have implemented ArrayAccess.
717 1
   *
718 1
   * @param \ArrayAccess $object <p>Object that implements ArrayAccess</p>
719 1
   *
720 1
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
721 1
   */
722 1
  public static function createFromObject(\ArrayAccess $object)
723
  {
724 1
    $array = new static();
725 1
    foreach ($object as $key => $value) {
726
      /** @noinspection OffsetOperationsInspection */
727 1
      $array[$key] = $value;
728
    }
729 1
730
    return $array;
731
  }
732
733
  /**
734
   * Create an new Arrayy object via string.
735
   *
736
   * @param string      $str       <p>The input string.</p>
737
   * @param string|null $delimiter <p>The boundary string.</p>
738
   * @param string|null $regEx     <p>Use the $delimiter or the $regEx, so if $pattern is null, $delimiter will be
739 8
   *                               used.</p>
740
   *
741 8
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
742
   */
743 8
  public static function createFromString($str, $delimiter, $regEx = null)
744
  {
745
    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...
746
      preg_match_all($regEx, $str, $array);
747
748
      if (!empty($array)) {
749
        $array = $array[0];
750
      }
751 1
752
    } else {
753 1
      $array = explode($delimiter, $str);
754
    }
755 1
756 1
    // trim all string in the array
757
    \array_walk(
758 1
        $array,
759
        function (&$val) {
760
          /** @noinspection ReferenceMismatchInspection */
761
          if (is_string($val)) {
762
            $val = trim($val);
763
          }
764
        }
765
    );
766
767
    return static::create($array);
768 4
  }
769
770 4
  /**
771
   * Create an new instance containing a range of elements.
772 4
   *
773 4
   * @param mixed $low  <p>First value of the sequence.</p>
774 4
   * @param mixed $high <p>The sequence is ended upon reaching the end value.</p>
775
   * @param int   $step <p>Used as the increment between elements in the sequence.</p>
776 4
   *
777
   * @return static <p>(Immutable) Returns an new instance of the Arrayy object.</p>
778
   */
779
  public static function createWithRange($low, $high, $step = 1)
780
  {
781
    return static::create(range($low, $high, $step));
782
  }
783
784
  /**
785
   * Custom sort by index via "uksort".
786 4
   *
787
   * @link http://php.net/manual/en/function.uksort.php
788 4
   *
789 4
   * @param callable $function
790 3
   *
791 1
   * @return static <p>(Mutable) Return this Arrayy object.</p>
792 1
   */
793
  public function customSortKeys($function)
794 4
  {
795
    uksort($this->array, $function);
796 4
797
    return $this;
798
  }
799
800
  /**
801
   * Custom sort by value via "usort".
802
   *
803
   * @link http://php.net/manual/en/function.usort.php
804
   *
805
   * @param callable $function
806
   *
807
   * @return static <p>(Mutable) Return this Arrayy object.</p>
808
   */
809
  public function customSortValues($function)
810
  {
811
    usort($this->array, $function);
812
813
    return $this;
814
  }
815
816 759
  /**
817
   * Return values that are only in the current array.
818 759
   *
819 756
   * @param array $array
820
   *
821
   * @return static <p>(Immutable)</p>
822 10
   */
823 1
  public function diff(array $array = array())
824
  {
825
    $result = \array_diff($this->array, $array);
826 9
827 6
    return static::create($result);
828
  }
829
830 8
  /**
831
   * Return values that are only in the current multi-dimensional array.
832
   *
833
   * @param array      $array
834
   * @param null|array $helperVariableForRecursion <p>(only for internal usage)</p>
835 8
   *
836
   * @return static <p>(Immutable)</p>
837
   */
838
  public function diffRecursive(array $array = array(), $helperVariableForRecursion = null)
839
  {
840
    $result = array();
841 8
842
    if (
843 2
        $helperVariableForRecursion !== null
844 8
        &&
845 6
        is_array($helperVariableForRecursion)
846
    ) {
847
      $arrayForTheLoop = $helperVariableForRecursion;
848 2
    } else {
849
      $arrayForTheLoop = $this->array;
850 2
    }
851
852
    foreach ($arrayForTheLoop as $key => $value) {
853
      if (\array_key_exists($key, $array)) {
854
        if (is_array($value)) {
855
          $recursiveDiff = $this->diffRecursive($array[$key], $value);
856
          if (!empty($recursiveDiff)) {
857
            $result[$key] = $recursiveDiff;
858
          }
859
        } else {
860 9
          if ($value != $array[$key]) {
861
            $result[$key] = $value;
862 9
          }
863 1
        }
864
      } else {
865
        $result[$key] = $value;
866 9
      }
867
    }
868 9
869
    return static::create($result);
870
  }
871
872
  /**
873
   * Return values that are only in the new $array.
874
   *
875
   * @param array $array
876
   *
877
   * @return static <p>(Immutable)</p>
878
   */
879
  public function diffReverse(array $array = array())
880
  {
881
    $result = \array_diff($array, $this->array);
882
883
    return static::create($result);
884
  }
885
886
  /**
887
   * Divide an array into two arrays. One with keys and the other with values.
888
   *
889
   * @return static <p>(Immutable)</p>
890
   */
891
  public function divide()
892
  {
893 1
    return static::create(
894
        array(
895 1
            $this->keys(),
896 1
            $this->values(),
897 1
        )
898
    );
899
  }
900
901 1
  /**
902 1
   * Iterate over the current array and modify the array's value.
903
   *
904
   * @param \Closure $closure
905 1
   *
906
   * @return static <p>(Immutable)</p>
907
   */
908 1 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...
909
  {
910
    $array = $this->array;
911 1
912
    foreach ($array as $key => $value) {
913 1
      $array[$key] = $closure($value, $key);
914 1
    }
915
916
    return static::create($array);
917 1
  }
918
919
  /**
920 1
   * Check if a value is in the current array using a closure.
921
   *
922
   * @param \Closure $closure
923 1
   *
924
   * @return bool <p>Returns true if the given value is found, false otherwise.</p>
925 1
   */
926 1
  public function exists(\Closure $closure)
927
  {
928
    $isExists = false;
929 1
    foreach ($this->array as $key => $value) {
930
      if ($closure($value, $key)) {
931
        $isExists = true;
932 1
        break;
933
      }
934
    }
935 1
936 1
    return $isExists;
937
  }
938 1
939 1
  /**
940 1
   * create a fallback for array
941
   *
942 1
   * 1. use the current array, if it's a array
943 1
   * 2. call "getArray()" on object, if there is a "Arrayy"-object
944 1
   * 3. fallback to empty array, if there is nothing
945 1
   * 4. call "createFromObject()" on object, if there is a "\ArrayAccess"-object
946
   * 5. call "__toArray()" on object, if the method exists
947 1
   * 6. cast a string or object with "__toString()" into an array
948 1
   * 7. throw a "InvalidArgumentException"-Exception
949 1
   *
950
   * @param $array
951 1
   *
952
   * @return array
953 1
   *
954 1
   * @throws \InvalidArgumentException
955
   */
956 1
  protected function fallbackForArray(&$array)
957
  {
958
    if (is_array($array)) {
959
      return $array;
960
    }
961
962
    if ($array instanceof self) {
963
      return $array->getArray();
964
    }
965
966
    if (!$array) {
967 8
      return array();
968
    }
969 8
970 6
    $isObject = is_object($array);
971 5
972
    if ($isObject && $array instanceof \ArrayAccess) {
973 5
      /** @noinspection ReferenceMismatchInspection */
974
      return static::createFromObject($array)->getArray();
975 3
    }
976
977
    if ($isObject && $array instanceof \ArrayObject) {
978
      return $array->getArrayCopy();
979
    }
980
981
    if ($isObject && method_exists($array, '__toArray')) {
982
      return (array)$array->__toArray();
983
    }
984
985
    /** @noinspection ReferenceMismatchInspection */
986
    if (
987
        is_string($array)
988
        ||
989
        ($isObject && method_exists($array, '__toString'))
990
    ) {
991
      return array((string)$array);
992
    }
993
994
    throw new \InvalidArgumentException(
995
        'Passed value should be a array'
996
    );
997 13
  }
998
999 13
  /**
1000 13
   * Find all items in an array that pass the truth test.
1001
   *
1002 13
   * @param \Closure|null $closure
1003 3
   *
1004
   * @return static <p>(Immutable)</p>
1005
   */
1006 10
  public function filter($closure = null)
1007
  {
1008
    if (!$closure) {
1009
      return $this->clean();
1010
    }
1011
1012
    $array = \array_filter($this->array, $closure);
1013
1014
    return static::create($array);
1015
  }
1016 28
1017
  /**
1018 28
   * Filters an array of objects (or a numeric array of associative arrays) based on the value of a particular property
1019 7
   * within that.
1020 7
   *
1021 7
   * @param string $property
1022 21
   * @param string $value
1023 21
   * @param string $comparisonOp
1024 21
   *                            <p>
1025
   *                            'eq' (equals),<br />
1026
   *                            'gt' (greater),<br />
1027 28
   *                            'gte' || 'ge' (greater or equals),<br />
1028
   *                            'lt' (less),<br />
1029
   *                            'lte' || 'le' (less or equals),<br />
1030
   *                            'ne' (not equals),<br />
1031
   *                            'contains',<br />
1032
   *                            'notContains',<br />
1033
   *                            'newer' (via strtotime),<br />
1034
   *                            'older' (via strtotime),<br />
1035
   *                            </p>
1036
   *
1037 26
   * @return static <p>(Immutable)</p>
1038
   */
1039 26
  public function filterBy($property, $value, $comparisonOp = null)
1040 11
  {
1041 11
    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...
1042 15
      $comparisonOp = is_array($value) ? 'contains' : 'eq';
1043 15
    }
1044
1045
    $ops = array(
1046 26
        'eq'          => function ($item, $prop, $value) {
1047
          return $item[$prop] === $value;
1048
        },
1049
        'gt'          => function ($item, $prop, $value) {
1050
          return $item[$prop] > $value;
1051
        },
1052
        'ge'          => function ($item, $prop, $value) {
1053
          return $item[$prop] >= $value;
1054 1
        },
1055
        'gte'         => function ($item, $prop, $value) {
1056 1
          return $item[$prop] >= $value;
1057
        },
1058 1
        'lt'          => function ($item, $prop, $value) {
1059
          return $item[$prop] < $value;
1060
        },
1061
        'le'          => function ($item, $prop, $value) {
1062
          return $item[$prop] <= $value;
1063
        },
1064
        'lte'         => function ($item, $prop, $value) {
1065
          return $item[$prop] <= $value;
1066
        },
1067
        'ne'          => function ($item, $prop, $value) {
1068
          return $item[$prop] !== $value;
1069
        },
1070
        'contains'    => function ($item, $prop, $value) {
1071 58
          return in_array($item[$prop], (array)$value, true);
1072
        },
1073
        'notContains' => function ($item, $prop, $value) {
1074
          return !in_array($item[$prop], (array)$value, true);
1075 58
        },
1076 3
        'newer'       => function ($item, $prop, $value) {
1077 58
          return strtotime($item[$prop]) > strtotime($value);
1078 3
        },
1079 3
        'older'       => function ($item, $prop, $value) {
1080 56
          return strtotime($item[$prop]) < strtotime($value);
1081
        },
1082
    );
1083 58
1084 1
    $result = \array_values(
1085
        \array_filter(
1086
            (array)$this->array,
1087
            function ($item) use (
1088 58
                $property,
1089 2
                $value,
1090 2
                $ops,
1091
                $comparisonOp
1092 58
            ) {
1093 48
              $item = (array)$item;
1094 5
              $itemArrayy = new Arrayy($item);
1095
              $item[$property] = $itemArrayy->get($property, array());
1096
1097 45
              return $ops[$comparisonOp]($item, $property, $value);
1098
            }
1099
        )
1100
    );
1101 19
1102 19
    return static::create($result);
1103 19
  }
1104
1105
  /**
1106 4
   * Find the first item in an array that passes the truth test,
1107 4
   *  otherwise return false
1108
   *
1109 4
   * @param \Closure $closure
1110
   *
1111
   * @return mixed|false <p>Return false if we did not find the value.</p>
1112
   */
1113 4
  public function find(\Closure $closure)
1114
  {
1115
    foreach ($this->array as $key => $value) {
1116
      if ($closure($value, $key)) {
1117
        return $value;
1118
      }
1119
    }
1120
1121 484
    return false;
1122
  }
1123 484
1124
  /**
1125 484
   * find by ...
1126
   *
1127
   * @param string $property
1128
   * @param string $value
1129
   * @param string $comparisonOp
1130
   *
1131 399
   * @return static <p>(Immutable)</p>
1132
   */
1133 399
  public function findBy($property, $value, $comparisonOp = 'eq')
1134
  {
1135
    return $this->filterBy($property, $value, $comparisonOp);
1136 399
  }
1137
1138
  /**
1139
   * Get the first value from the current array.
1140
   *
1141
   * @return mixed <p>Return null if there wasn't a element.</p>
1142
   */
1143
  public function first()
1144
  {
1145
    $tmpArray = $this->array;
1146
    $result = \array_shift($tmpArray);
1147
1148
    if ($result === null) {
1149
      return null;
1150 1
    }
1151
1152 1
    return $result;
1153
  }
1154 1
1155
  /**
1156
   * Get the first value(s) from the current array.
1157
   *
1158
   * @param int|null $number <p>How many values you will take?</p>
1159
   *
1160
   * @return static <p>(Immutable)</p>
1161
   */
1162
  public function firstsImmutable($number = null)
1163
  {
1164 38
    if ($number === null) {
1165
      $arrayTmp = $this->array;
1166 38
      $array = (array)\array_shift($arrayTmp);
1167 10
    } else {
1168
      $number = (int)$number;
1169 10
      $arrayTmp = $this->array;
1170 2
      $array = \array_splice($arrayTmp, 0, $number, true);
1171 2
    }
1172 8
1173
    return static::create($array);
1174 10
  }
1175
1176
  /**
1177
   * Get the first value(s) from the current array.
1178 38
   *
1179
   * @param int|null $number <p>How many values you will take?</p>
1180 38
   *
1181
   * @return static <p>(Mutable)</p>
1182
   */
1183
  public function firstsMutable($number = null)
1184 38
  {
1185
    if ($number === null) {
1186
      $this->array = (array)\array_shift($this->array);
1187
    } else {
1188
      $number = (int)$number;
1189
      $this->array = \array_splice($this->array, 0, $number, true);
1190
    }
1191
1192
    return $this;
1193
  }
1194 1
1195
  /**
1196 1
   * Exchanges all keys with their associated values in an array.
1197
   *
1198
   * @return static <p>(Immutable)</p>
1199
   */
1200
  public function flip()
1201
  {
1202
    $result = \array_flip($this->array);
1203
1204
    return static::create($result);
1205
  }
1206 3
1207
  /**
1208 3
   * Get a value from an array (optional using dot-notation).
1209
   *
1210
   * @param string $key      <p>The key to look for.</p>
1211
   * @param mixed  $fallback <p>Value to fallback to.</p>
1212
   * @param array  $array    <p>The array to get from, if it's set to "null" we use the current array from the
1213
   *                         class.</p>
1214
   *
1215
   * @return mixed
1216
   */
1217
  public function get($key, $fallback = null, $array = null)
1218 3
  {
1219
    if (
1220 3
        $array !== null
1221
        &&
1222
        is_array($array)
1223
    ) {
1224
      $usedArray = $array;
1225
    } else {
1226
      $usedArray = $this->array;
1227
    }
1228
1229
    if ($key === null) {
1230
      return static::create($usedArray);
1231
    }
1232 9
1233
    // php cast "bool"-index into "int"-index
1234 9
    if ((bool)$key === $key) {
1235
      $key = (int)$key;
1236
    }
1237
1238
    if (\array_key_exists($key, $usedArray) === true) {
1239
      if (is_array($usedArray[$key])) {
1240
        return static::create($usedArray[$key]);
1241
      }
1242
1243
      return $usedArray[$key];
1244 3
    }
1245
1246 3
    // Crawl through array, get key according to object or not
1247
    foreach (explode($this->pathSeparator, (string)$key) as $segment) {
1248
      if (!isset($usedArray[$segment])) {
1249
        return $fallback instanceof \Closure ? $fallback() : $fallback;
1250
      }
1251
1252
      $usedArray = $usedArray[$segment];
1253
    }
1254
1255
    if (is_array($usedArray)) {
1256
      return static::create($usedArray);
1257
    }
1258 6
1259
    return $usedArray;
1260 6
  }
1261
1262
  /**
1263
   * Get the current array from the "Arrayy"-object.
1264
   *
1265
   * @return array
1266
   */
1267
  public function getArray()
1268
  {
1269
    \array_map(array('self', 'internalGetArray'), $this->array);
1270
1271 3
    return $this->array;
1272
  }
1273 3
1274 3
  /**
1275
   * Returns the values from a single column of the input array, identified by
1276
   * the $columnKey, can be used to extract data-columns from multi-arrays.
1277 3
   *
1278
   * Info: Optionally, you may provide an $indexKey to index the values in the returned
1279 3
   * array by the values from the $indexKey column in the input array.
1280 3
   *
1281
   * @param mixed $columnKey
1282 3
   * @param mixed $indexKey
1283
   *
1284
   * @return static <p>(Immutable)</p>
1285
   */
1286 3
  public function getColumn($columnKey = null, $indexKey = null)
1287 3
  {
1288 3
    $result = \array_column($this->array, $columnKey, $indexKey);
1289
1290
    return static::create($result);
1291 3
  }
1292 2
1293 1
  /**
1294 1
   * Get correct PHP constant for direction.
1295 1
   *
1296 1
   * @param int|string $direction
1297 1
   *
1298
   * @return int
1299 2
   */
1300
  protected function getDirection($direction)
1301 3
  {
1302
    if (is_string($direction)) {
1303 3
      $direction = strtolower($direction);
1304
1305
      if ($direction === 'desc') {
1306
        $direction = SORT_DESC;
1307
      } else {
1308
        $direction = SORT_ASC;
1309
      }
1310
    }
1311
1312
    if (
1313 22
        $direction !== SORT_DESC
1314
        &&
1315
        $direction !== SORT_ASC
1316 22
    ) {
1317
      $direction = SORT_ASC;
1318 22
    }
1319
1320
    return $direction;
1321
  }
1322
1323
  /**
1324
   * alias: for "Arrayy->keys()"
1325
   *
1326
   * @see Arrayy::keys()
1327
   *
1328 27
   * @return static <p>(Immutable)</p>
1329
   */
1330 27
  public function getKeys()
1331
  {
1332
    return $this->keys();
1333
  }
1334
1335
  /**
1336
   * alias: for "Arrayy->randomImmutable()"
1337
   *
1338
   * @see Arrayy::randomImmutable()
1339
   *
1340
   * @return static <p>(Immutable)</p>
1341
   */
1342
  public function getRandom()
1343
  {
1344 3
    return $this->randomImmutable();
1345
  }
1346 3
1347
  /**
1348 3
   * alias: for "Arrayy->randomKey()"
1349 3
   *
1350 2
   * @see Arrayy::randomKey()
1351 2
   *
1352 3
   * @return mixed <p>Get a key/index or null if there wasn't a key/index.</p>
1353
   */
1354 3
  public function getRandomKey()
1355
  {
1356
    return $this->randomKey();
1357
  }
1358
1359
  /**
1360
   * alias: for "Arrayy->randomKeys()"
1361
   *
1362
   * @see Arrayy::randomKeys()
1363
   *
1364
   * @param int $number
1365
   *
1366 4
   * @return static <p>(Immutable)</p>
1367
   */
1368 4
  public function getRandomKeys($number)
1369
  {
1370
    return $this->randomKeys($number);
1371
  }
1372
1373
  /**
1374
   * alias: for "Arrayy->randomValue()"
1375
   *
1376
   * @see Arrayy::randomValue()
1377
   *
1378 12
   * @return mixed <p>get a random value or null if there wasn't a value.</p>
1379
   */
1380 12
  public function getRandomValue()
1381
  {
1382 12
    return $this->randomValue();
1383
  }
1384
1385
  /**
1386
   * alias: for "Arrayy->randomValues()"
1387
   *
1388
   * @see Arrayy::randomValues()
1389
   *
1390
   * @param int $number
1391
   *
1392 18
   * @return static <p>(Immutable)</p>
1393
   */
1394 18
  public function getRandomValues($number)
1395
  {
1396
    return $this->randomValues($number);
1397 18
  }
1398
1399
  /**
1400
   * Group values from a array according to the results of a closure.
1401
   *
1402
   * @param string $grouper <p>A callable function name.</p>
1403
   * @param bool   $saveKeys
1404
   *
1405
   * @return static <p>(Immutable)</p>
1406
   */
1407 18
  public function group($grouper, $saveKeys = false)
1408
  {
1409 18
    $array = (array)$this->array;
1410
    $result = array();
1411 18
1412
    // Iterate over values, group by property/results from closure
1413
    foreach ($array as $key => $value) {
1414
1415
      $groupKey = is_callable($grouper) ? $grouper($value, $key) : $this->get($grouper, null, $value);
1416
      $newValue = $this->get($groupKey, null, $result);
1417
1418
      if ($groupKey instanceof self) {
1419
        $groupKey = $groupKey->getArray();
1420
      }
1421
1422 28
      if ($newValue instanceof self) {
1423
        $newValue = $newValue->getArray();
1424 28
      }
1425
1426
      // Add to results
1427
      if ($groupKey !== null) {
1428
        if ($saveKeys) {
1429 28
          $result[$groupKey] = $newValue;
1430 28
          $result[$groupKey][$key] = $value;
1431
        } else {
1432
          $result[$groupKey] = $newValue;
1433 28
          $result[$groupKey][] = $value;
1434 2
        }
1435
      }
1436
1437
    }
1438
1439 2
    return static::create($result);
1440
  }
1441
1442
  /**
1443 2
   * Check if an array has a given key.
1444 2
   *
1445
   * @param mixed $key
1446 28
   *
1447
   * @return bool
1448 28
   */
1449
  public function has($key)
1450
  {
1451
    // Generate unique string to use as marker.
1452
    $unFound = (string)uniqid('arrayy', true);
1453
1454
    return $this->get($key, $unFound) !== $unFound;
1455
  }
1456
1457
  /**
1458 2
   * Implodes an array.
1459
   *
1460 2
   * @param string $glue
1461
   *
1462
   * @return string
1463
   */
1464
  public function implode($glue = '')
1465
  {
1466
    return implode($glue, $this->array);
1467
  }
1468
1469
  /**
1470 1
   * Given a list and an iterate-function that returns
1471
   * a key for each element in the list (or a property name),
1472 1
   * returns an object with an index of each item.
1473
   *
1474
   * Just like groupBy, but for when you know your keys are unique.
1475
   *
1476
   * @param mixed $key
1477
   *
1478
   * @return static <p>(Immutable)</p>
1479
   */
1480
  public function indexBy($key)
1481
  {
1482
    $results = array();
1483 1
1484
    foreach ($this->array as $a) {
1485
      if (\array_key_exists($key, $a) === true) {
1486 1
        $results[$a[$key]] = $a;
1487 1
      }
1488 1
    }
1489
1490
    return static::create($results);
1491 1
  }
1492 1
1493 1
  /**
1494 1
   * alias: for "Arrayy->searchIndex()"
1495
   *
1496
   * @see Arrayy::searchIndex()
1497 1
   *
1498
   * @param mixed $value <p>The value to search for.</p>
1499
   *
1500
   * @return mixed
1501
   */
1502
  public function indexOf($value)
1503
  {
1504
    return $this->searchIndex($value);
1505 15
  }
1506
1507 15
  /**
1508 3
   * Get everything but the last..$to items.
1509
   *
1510
   * @param int $to
1511 13
   *
1512 13
   * @return static <p>(Immutable)</p>
1513 11
   */
1514
  public function initial($to = 1)
1515 3
  {
1516
    $slice = count($this->array) - $to;
1517 3
1518
    return $this->firstsImmutable($slice);
1519
  }
1520
1521
  /**
1522
   * @param mixed $value
1523
   */
1524
  protected function internalGetArray(&$value)
1525 85
  {
1526
    if ($value instanceof self) {
1527 85
      $value &= $value->getArray();
1528
    } 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...
1529
      $value &= $value->jsonSerialize();
1530
    }
1531
  }
1532
1533
  /**
1534
   * Internal mechanics of remove method.
1535
   *
1536
   * @param string $key
1537
   *
1538
   * @return boolean
1539
   */
1540
  protected function internalRemove($key)
1541
  {
1542
    $path = explode($this->pathSeparator, (string)$key);
1543
1544
    // Crawl though the keys
1545
    while (count($path) > 1) {
1546
      $key = \array_shift($path);
1547 14
1548
      if (!$this->has($key)) {
1549 14
        return false;
1550
      }
1551
1552
      $this->array = &$this->array[$key];
1553
    }
1554
1555
    $key = \array_shift($path);
1556
1557 5
    unset($this->array[$key]);
1558
1559 5
    return true;
1560 2
  }
1561
1562
  /**
1563 4
   * Internal mechanic of set method.
1564 4
   *
1565 2
   * @param string $key
1566
   * @param mixed  $value
1567 3
   *
1568
   * @return bool
1569 2
   */
1570
  protected function internalSet($key, $value)
1571
  {
1572
    if ($key === null) {
1573
      return false;
1574
    }
1575
1576
    // init
1577 1
    $array =& $this->array;
1578
    $path = explode($this->pathSeparator, (string)$key);
1579 1
1580
    // Crawl through the keys
1581
    while (count($path) > 1) {
1582
      $key = \array_shift($path);
1583
1584
      // If the key doesn't exist at this depth, we will just create an empty array
1585
      // to hold the next value, allowing us to create the arrays to hold final
1586
      // values at the correct depth. Then we'll keep digging into the array.
1587 25
      if (!isset($array[$key]) || !is_array($array[$key])) {
1588
        $array[$key] = static::create(array());
1589 25
      }
1590
1591
      $array =& $array[$key];
1592
    }
1593
1594
    $array[\array_shift($path)] = $value;
1595
1596
    return true;
1597 4
  }
1598
1599 4
  /**
1600
   * Return an array with all elements found in input array.
1601
   *
1602
   * @param array $search
1603
   *
1604
   * @return static <p>(Immutable)</p>
1605
   */
1606
  public function intersection(array $search)
1607
  {
1608
    return static::create(\array_values(\array_intersect($this->array, $search)));
1609 13
  }
1610
1611 13
  /**
1612 1
   * Return a boolean flag which indicates whether the two input arrays have any common elements.
1613
   *
1614
   * @param array $search
1615 12
   *
1616 8
   * @return bool
1617
   */
1618 8
  public function intersects(array $search)
1619 1
  {
1620 1
    return count($this->intersection($search)->array) > 0;
1621 7
  }
1622
1623
  /**
1624 8
   * Invoke a function on all of an array's values.
1625 8
   *
1626 4
   * @param mixed $callable
1627 4
   * @param mixed $arguments
1628
   *
1629
   * @return static <p>(Immutable)</p>
1630 12
   */
1631
  public function invoke($callable, $arguments = array())
1632
  {
1633
    // If one argument given for each iteration, create an array for it.
1634
    if (!is_array($arguments)) {
1635
      $arguments = StaticArrayy::repeat($arguments, count($this->array))->getArray();
1636
    }
1637
1638
    // If the callable has arguments, pass them.
1639
    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...
1640 13
      $array = \array_map($callable, $this->array, $arguments);
1641
    } else {
1642 13
      $array = \array_map($callable, $this->array);
1643 1
    }
1644
1645
    return static::create($array);
1646 12
  }
1647 8
1648
  /**
1649 8
   * Check whether array is associative or not.
1650 1
   *
1651 1
   * @return bool <p>Returns true if associative, false otherwise.</p>
1652 7
   */
1653
  public function isAssoc()
1654
  {
1655 8
    if ($this->isEmpty()) {
1656 8
      return false;
1657 4
    }
1658 4
1659
    foreach ($this->keys()->getArray() as $key) {
1660
      if (!is_string($key)) {
1661 12
        return false;
1662
      }
1663
    }
1664
1665
    return true;
1666
  }
1667
1668
  /**
1669
   * Check whether the array is empty or not.
1670
   *
1671
   * @return bool <p>Returns true if empty, false otherwise.</p>
1672
   */
1673 10
  public function isEmpty()
1674
  {
1675 10
    return !$this->array;
1676
  }
1677
1678
  /**
1679
   * Check if the current array is equal to the given "$array" or not.
1680
   *
1681
   * @param array $array
1682
   *
1683
   * @return bool
1684
   */
1685
  public function isEqual(array $array)
1686 4
  {
1687
    return ($this->array === $array);
1688 4
  }
1689
1690 4
  /**
1691
   * Check if the current array is a multi-array.
1692
   *
1693
   * @return bool
1694
   */
1695
  public function isMultiArray()
1696
  {
1697
    return !(count($this->array) === count($this->array, COUNT_RECURSIVE));
1698
  }
1699
1700 15
  /**
1701
   * Check whether array is numeric or not.
1702 15
   *
1703 2
   * @return bool <p>Returns true if numeric, false otherwise.</p>
1704
   */
1705
  public function isNumeric()
1706
  {
1707 13
    if ($this->isEmpty()) {
1708
      return false;
1709 13
    }
1710 13
1711
    foreach ($this->keys() as $key) {
1712 13
      if (!is_int($key)) {
1713 7
        return false;
1714
      }
1715 9
    }
1716
1717 7
    return true;
1718
  }
1719
1720
  /**
1721
   * Check if the current array is sequential [0, 1, 2, 3, 4, 5 ...] or not.
1722
   *
1723
   * @return bool
1724
   */
1725
  public function isSequential()
1726
  {
1727 14
    return \array_keys($this->array) === range(0, count($this->array) - 1);
1728
  }
1729 14
1730 2
  /**
1731
   * @return array
1732
   */
1733
  public function jsonSerialize()
1734 12
  {
1735
    return $this->getArray();
1736 12
  }
1737 12
1738
  /**
1739 12
   * Get all keys from the current array.
1740 9
   *
1741
   * @return static <p>(Immutable)</p>
1742 5
   */
1743
  public function keys()
1744 4
  {
1745
    return static::create(\array_keys($this->array));
1746
  }
1747
1748
  /**
1749
   * Get the last value from the current array.
1750
   *
1751
   * @return mixed <p>Return null if there wasn't a element.</p>
1752 10
   */
1753
  public function last()
1754 10
  {
1755 1
    return $this->pop();
1756
  }
1757
1758 9
  /**
1759
   * Get the last value(s) from the current array.
1760
   *
1761
   * @param int|null $number
1762
   *
1763
   * @return static <p>(Immutable)</p>
1764
   */
1765
  public function lastsImmutable($number = null)
1766
  {
1767
    if ($this->isEmpty()) {
1768
      return static::create();
1769
    }
1770
1771 25
    if ($number === null) {
1772
      $poppedValue = $this->pop();
1773 25
1774 4
      if ($poppedValue === null) {
1775 4
        $poppedValue = array($poppedValue);
1776 21
      } else {
1777
        $poppedValue = (array)$poppedValue;
1778
      }
1779 25
1780
      $arrayy = static::create($poppedValue);
1781
    } else {
1782
      $number = (int)$number;
1783
      $arrayy = $this->rest(-$number);
1784
    }
1785
1786
    return $arrayy;
1787
  }
1788
1789
  /**
1790
   * Get the last value(s) from the current array.
1791
   *
1792
   * @param int|null $number
1793 16
   *
1794
   * @return static <p>(Mutable)</p>
1795 16
   */
1796 4
  public function lastsMutable($number = null)
1797 4
  {
1798 12
    if ($this->isEmpty()) {
1799
      return $this;
1800
    }
1801 16
1802
    if ($number === null) {
1803
      $poppedValue = $this->pop();
1804
1805
      if ($poppedValue === null) {
1806
        $poppedValue = array($poppedValue);
1807
      } else {
1808
        $poppedValue = (array)$poppedValue;
1809
      }
1810
1811
      $this->array = static::create($poppedValue)->array;
1812
    } else {
1813
      $number = (int)$number;
1814 16
      $this->array = $this->rest(-$number)->array;
1815
    }
1816 16
1817 4
    return $this;
1818 4
  }
1819 12
1820
  /**
1821
   * Count the values from the current array.
1822 16
   *
1823
   * alias: for "Arrayy->size()"
1824
   *
1825
   * @see Arrayy::size()
1826
   *
1827
   * @return int
1828
   */
1829
  public function length()
1830
  {
1831
    return $this->size();
1832
  }
1833
1834
  /**
1835
   * Apply the given function to the every element of the array,
1836 16
   * collecting the results.
1837
   *
1838 16
   * @param callable $callable
1839 4
   *
1840 4
   * @return static <p>(Immutable) Arrayy object with modified elements.</p>
1841 12
   */
1842
  public function map($callable)
1843
  {
1844 16
    $result = \array_map($callable, $this->array);
1845
1846
    return static::create($result);
1847
  }
1848
1849
  /**
1850
   * Check if all items in current array match a truth test.
1851
   *
1852 10
   * @param \Closure $closure
1853
   *
1854 10
   * @return bool
1855 1
   */
1856 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...
1857
  {
1858 9
    if (count($this->array) === 0) {
1859
      return false;
1860
    }
1861
1862
    // init
1863
    $array = $this->array;
1864
1865
    foreach ($array as $key => $value) {
1866
      $value = $closure($value, $key);
1867
1868
      if ($value === false) {
1869
        return false;
1870
      }
1871
    }
1872
1873
    return true;
1874
  }
1875
1876
  /**
1877
   * Check if any item in the current array matches a truth test.
1878
   *
1879
   * @param \Closure $closure
1880
   *
1881
   * @return bool
1882
   */
1883 4 View Code Duplication
  public function matchesAny(\Closure $closure)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1884
  {
1885 4
    if (count($this->array) === 0) {
1886
      return false;
1887 4
    }
1888
1889
    // init
1890
    $array = $this->array;
1891
1892
    foreach ($array as $key => $value) {
1893
      $value = $closure($value, $key);
1894
1895 16
      if ($value === true) {
1896
        return true;
1897 16
      }
1898
    }
1899
1900
    return false;
1901
  }
1902
1903
  /**
1904
   * Get the max value from an array.
1905
   *
1906
   * @return mixed
1907
   */
1908 8
  public function max()
1909
  {
1910 8
    if ($this->count() === 0) {
1911 8
      return false;
1912 8
    }
1913
1914 1
    return max($this->array);
1915
  }
1916
1917 8
  /**
1918
   * Merge the new $array into the current array.
1919
   *
1920
   * - keep key,value from the current array, also if the index is in the new $array
1921
   *
1922
   * @param array $array
1923
   * @param bool  $recursive
1924
   *
1925 4
   * @return static <p>(Immutable)</p>
1926
   */
1927 4 View Code Duplication
  public function mergeAppendKeepIndex(array $array = array(), $recursive = false)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

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