GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Failed
Push — master ( 17698f...1cf5ae )
by Marios
02:35
created

ArraysMethods::flatten()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
c 0
b 0
f 0
dl 0
loc 32
rs 8.8333
cc 7
nc 16
nop 3
1
<?php
2
3
/*
4
 * This file is part of Underscore.php
5
 *
6
 * (c) Maxime Fabre <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Underscore\Methods;
13
14
use Closure;
15
16
/**
17
 * Methods to manage arrays.
18
 */
19
class ArraysMethods extends CollectionMethods
20
{
21
22
    ////////////////////////////////////////////////////////////////////
23
    ///////////////////////////// GENERATE /////////////////////////////
24
    ////////////////////////////////////////////////////////////////////
25
26
    //<editor-fold desc="*** Methods ***">
27
    /**
28
     * Generate an array from a range.
29
     *
30
     * @param int $_base The base number
31
     * @param int $stop  The stopping point
32
     * @param int $step  How many to increment of
33
     *
34
     * @return array
35
     */
36
    public static function range($_base, $stop = null, $step = 1) : array
37
    {
38
        // Dynamic arguments
39
        if ($stop !== null) {
40
            $start = $_base;
41
        }
42
        else {
43
            $start = 1;
44
            $stop  = $_base;
45
        }
46
47
        return range($start, $stop, $step);
48
    }
49
50
    /**
51
     * Fill an array with $times times some $data.
52
     *
53
     * @param mixed $data
54
     * @param int   $times
55
     *
56
     * @return array
57
     */
58
    public static function repeat($data, int $times) : array
59
    {
60
        $times = (int)(abs($times));
61
        if ($times === 0) {
62
            return [];
63
        }
64
65
        return array_fill(0, $times, $data);
66
    }
67
68
    ////////////////////////////////////////////////////////////////////
69
    ///////////////////////////// ANALYZE //////////////////////////////
70
    ////////////////////////////////////////////////////////////////////
71
72
    /**
73
     * Search for the index of a value in an array.
74
     *
75
     * @param array  $array
76
     * @param string $value
77
     *
78
     * @return mixed
79
     */
80
    public static function search($array, $value)
81
    {
82
        return array_search($value, $array, true);
83
    }
84
85
    /**
86
     * Check if all items in an array match a truth test.
87
     *
88
     * @param array    $array
89
     * @param callable $closure
90
     *
91
     * @return bool
92
     */
93
    public static function matches($array, callable $closure) : bool
94
    {
95
        // Reduce the array to only booleans
96
        $array = static::each($array, $closure);
97
98
        // Check the results
99
        if (\count($array) === 0) {
100
            return true;
101
        }
102
        $array = array_search(false, $array, false);
103
104
        return \is_bool($array);
105
    }
106
107
    /**
108
     * Check if any item in an array matches a truth test.
109
     *
110
     * @param array    $array
111
     * @param callable $closure
112
     *
113
     * @return bool
114
     */
115
    public static function matchesAny(array $array, callable $closure) : bool
116
    {
117
        // Reduce the array to only booleans
118
        $array = static::each($array, $closure);
119
120
        // Check the results
121
        if (\count($array) === 0) {
122
            return true;
123
        }
124
        $array = array_search(true, $array, false);
125
126
        return \is_int($array);
127
    }
128
129
    /**
130
     * Check if an item is in an array.
131
     *
132
     * @param $array
133
     * @param $value
134
     *
135
     * @return bool
136
     */
137
    public static function contains($array, $value) : bool
138
    {
139
        return \in_array($value, $array, true);
140
    }
141
142
    /**
143
     * Returns the average value of an array.
144
     *
145
     * @param array $array    The source array
146
     * @param int   $decimals The number of decimals to return
147
     *
148
     * @return float The average value
149
     */
150
    public static function average(array $array, int $decimals = 0) : float
151
    {
152
        return round((array_sum($array) / \count($array)), $decimals);
153
    }
154
155
    /**
156
     * Get the size of an array.
157
     *
158
     * @param array $array
159
     *
160
     * @return int
161
     */
162
    public static function size(array $array) : int
163
    {
164
        return \count($array);
165
    }
166
167
    /**
168
     * Get the max value from an array.
169
     *
170
     * @param array        $array
171
     * @param Closure|null $closure
172
     *
173
     * @return mixed
174
     */
175
    public static function max(array $array, $closure = null)
176
    {
177
        // If we have a closure, apply it to the array
178
        if ($closure) {
179
            $array = static::each($array, $closure);
180
        }
181
182
        return max($array);
183
    }
184
185
    /**
186
     * Get the min value from an array.
187
     *
188
     * @param array        $array
189
     * @param Closure|null $closure
190
     *
191
     * @return mixed
192
     */
193
    public static function min(array $array, $closure = null)
194
    {
195
        // If we have a closure, apply it to the array
196
        if ($closure) {
197
            $array = static::each($array, $closure);
198
        }
199
200
        return min($array);
201
    }
202
203
    ////////////////////////////////////////////////////////////////////
204
    //////////////////////////// FETCH FROM ////////////////////////////
205
    ////////////////////////////////////////////////////////////////////
206
207
    /**
208
     * Find the first item in an array that passes the truth test.
209
     *
210
     * @param array   $array
211
     * @param Closure $closure
212
     *
213
     * @return mixed|void
214
     */
215
    public static function find(array $array, Closure $closure)
216
    {
217
        foreach ($array as $key => $value) {
218
            if ($closure($value, $key)) {
219
                return $value;
220
            }
221
        }
222
223
        return;
224
    }
225
226
    /**
227
     * Clean all falsy values from an array.
228
     *
229
     * @param array $array
230
     *
231
     * @return array|mixed
232
     */
233
    public static function clean(array $array)
234
    {
235
        return static::filter($array, function($value) {
236
            return (bool)$value;
237
        });
238
    }
239
240
    /**
241
     * Get a random string from an array.
242
     *
243
     * @param array    $array
244
     * @param int|null $take
245
     *
246
     * @return array|mixed
247
     */
248
    public static function random(array $array, int $take = null)
249
    {
250
        if ( ! $take) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $take of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
251
            return $array[array_rand($array)];
252
        }
253
254
        shuffle($array);
255
256
        return static::first($array, $take);
257
    }
258
259
    /**
260
     * Return an array without all instances of certain values.
261
     */
262
    public static function without()
263
    {
264
        $arguments = \func_get_args();
265
        $array     = array_shift($arguments);
266
        // if singular argument and is an array treat this AS the array to run without agains
267
        if (\is_array($arguments[0]) && \count($arguments) === 1) {
268
            $arguments = $arguments[0];
269
        }
270
271
        return static::filter($array, function($value) use ($arguments) {
272
            return ! \in_array($value, $arguments, true);
273
        });
274
    }
275
276
    /**
277
     * Return an array with all elements found in both input arrays.
278
     *
279
     * @param array $a
280
     * @param array $b
281
     *
282
     * @return array
283
     */
284
    public static function intersection(array $a, array $b) : array
285
    {
286
        $a = (array)$a;
287
        $b = (array)$b;
288
289
        return array_values(array_intersect($a, $b));
290
    }
291
292
    /**
293
     * Return a boolean flag which indicates whether the two input arrays have any common elements.
294
     *
295
     * @param array $a
296
     * @param array $b
297
     *
298
     * @return bool
299
     */
300
    public static function intersects(array $a, array $b) : bool
301
    {
302
        $a = (array)$a;
303
        $b = (array)$b;
304
305
        return \count(self::intersection($a, $b)) > 0;
306
    }
307
308
    ////////////////////////////////////////////////////////////////////
309
    ///////////////////////////// SLICERS //////////////////////////////
310
    ////////////////////////////////////////////////////////////////////
311
312
    /**
313
     * Get the first value from an array.
314
     *
315
     * @param array    $array
316
     * @param int|null $take
317
     *
318
     * @return array|mixed
319
     */
320
    public static function first(array $array, int $take = null)
321
    {
322
        if ( ! $take) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $take of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
323
            return array_shift($array);
324
        }
325
326
        return array_splice($array, 0, $take, true);
327
    }
328
329
    /**
330
     * Get the last value from an array.
331
     *
332
     * @param array    $array
333
     * @param int|null $take
334
     *
335
     * @return array|mixed
336
     */
337
    public static function last(array $array, int $take = null)
338
    {
339
        if ( ! $take) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $take of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. 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 integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
340
            return array_pop($array);
341
        }
342
343
        return static::rest($array, -$take);
344
    }
345
346
    /**
347
     * Get everything but the last $to items.
348
     *
349
     * @param array $array
350
     * @param int   $to
351
     *
352
     * @return array|mixed
353
     */
354
    public static function initial(array $array, $to = 1)
355
    {
356
        $slice = \count($array) - $to;
357
358
        return static::first($array, $slice);
359
    }
360
361
    /**
362
     * Get the last elements from index $from.
363
     *
364
     * @param array $array
365
     * @param int   $from
366
     *
367
     * @return array
368
     */
369
    public static function rest(array $array, $from = 1) : array
370
    {
371
        return array_splice($array, $from);
372
    }
373
374
    ////////////////////////////////////////////////////////////////////
375
    ///////////////////////////// ACT UPON /////////////////////////////
376
    ////////////////////////////////////////////////////////////////////
377
378
    /**
379
     * Iterate over an array and execute a callback for each loop.
380
     *
381
     * @param array   $array
382
     * @param Closure $closure
383
     *
384
     * @return array
385
     */
386
    public static function at(array $array, Closure $closure) : array
387
    {
388
        foreach ($array as $key => $value) {
389
            $closure($value, $key);
390
        }
391
392
        return $array;
393
    }
394
395
    ////////////////////////////////////////////////////////////////////
396
    ////////////////////////////// ALTER ///////////////////////////////
397
    ////////////////////////////////////////////////////////////////////
398
399
    /**
400
     * Replace a value in an array.
401
     *
402
     * @param array  $array   The array
403
     * @param string $replace The string to replace
404
     * @param string $with    What to replace it with
405
     *
406
     * @return array
407
     */
408
    public static function replaceValue(array $array, string $replace, string $with) : array
409
    {
410
        return static::each($array, function($value) use ($replace, $with) {
411
            return str_replace($replace, $with, $value);
412
        });
413
    }
414
415
    /**
416
     * Replace the keys in an array with another set.
417
     *
418
     * @param array $array The array
419
     * @param array $keys  An array of keys matching the array's size
420
     *
421
     * @return array
422
     */
423
    public static function replaceKeys(array $array, array $keys) : array
424
    {
425
        $values = array_values($array);
426
427
        return array_combine($keys, $values);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_combine($keys, $values) could return the type false which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
428
    }
429
430
    /**
431
     * Iterate over an array and modify the array's value.
432
     *
433
     * @param array   $array
434
     * @param Closure $closure
435
     *
436
     * @return array
437
     */
438
    public static function each(array $array, Closure $closure) : array
439
    {
440
        foreach ($array as $key => $value) {
441
            $array[$key] = $closure($value, $key);
442
        }
443
444
        return $array;
445
    }
446
447
    /**
448
     * Shuffle an array.
449
     *
450
     * @param array $array
451
     *
452
     * @return array
453
     */
454
    public static function shuffle(array $array) : array
455
    {
456
        shuffle($array);
457
458
        return $array;
459
    }
460
461
    /**
462
     * Sort an array by key.
463
     *
464
     * @param array  $array
465
     * @param string $direction
466
     *
467
     * @return array
468
     */
469
    public static function sortKeys(array $array, string $direction = 'ASC') : array
470
    {
471
        $direction = (strtolower($direction) === 'desc') ? SORT_DESC : SORT_ASC;
472
        if ($direction === SORT_ASC) {
473
            ksort($array);
474
        }
475
        else {
476
            krsort($array);
477
        }
478
479
        return $array;
480
    }
481
482
    /**
483
     * Implodes an array.
484
     *
485
     * @param array  $array The array
486
     * @param string $with  What to implode it with
487
     *
488
     * @return string
489
     */
490
    public static function implode($array, $with = '') : string
491
    {
492
        return implode($with, $array);
493
    }
494
495
    /**
496
     * Find all items in an array that pass the truth test.
497
     *
498
     * @param array         $array
499
     * @param callable|null $closure
500
     *
501
     * @return array|mixed
502
     */
503
    public static function filter(array $array, $closure = null)
504
    {
505
        if ( ! $closure) {
506
            return static::clean($array);
507
        }
508
509
        return array_filter($array, $closure);
510
    }
511
512
    /**
513
     * Flattens an array to dot notation.
514
     *
515
     * @param array  $array     An array
516
     * @param string $separator The characater to flatten with
517
     * @param string $parent    The parent passed to the child (private)
518
     *
519
     * @return string|array Flattened array to one level
520
     */
521
    public static function flatten(array $array, string $separator = '.', string $parent = null)
522
    {
523
        if ( ! \is_array($array)) {
0 ignored issues
show
introduced by
The condition is_array($array) is always true.
Loading history...
524
            return $array;
525
        }
526
527
        $_flattened = [];
528
529
        // Rewrite keys
530
        foreach ($array as $key => $value) {
531
            if ($parent) {
532
                $key = $parent.$separator.$key;
533
            }
534
            if ( ! \is_array($value)) {
535
                $_flattened[$key] = $value;
536
                continue;
537
            }
538
            $_flattened[$key] = static::flatten($value, $separator, $key);
539
        }
540
541
        // Flatten
542
        $flattened = [];
543
        foreach ($_flattened as $key => $value) {
544
            if (\is_array($value)) {
545
                $flattened = array_merge($flattened, $value);
546
            }
547
            else {
548
                $flattened[$key] = $value;
549
            }
550
        }
551
552
        return $flattened;
553
    }
554
555
    /**
556
     * Invoke a function on all of an array's values.
557
     *
558
     * @param array        $array
559
     * @param callable     $callable
560
     * @param array|string $arguments
561
     *
562
     * @return array
563
     */
564
    public static function invoke(array $array, $callable, $arguments = []) : array
565
    {
566
        // If one argument given for each iteration, create an array for it
567
        if ( ! \is_array($arguments)) {
568
            $arguments = static::repeat($arguments, \count($array));
569
        }
570
571
        // If the callable has arguments, pass them
572
        if ($arguments) {
573
            return array_map($callable, $array, $arguments);
574
        }
575
576
        return array_map($callable, $array);
577
    }
578
579
    /**
580
     * Return all items that fail the truth test.
581
     *
582
     * @param array   $array
583
     * @param Closure $closure
584
     *
585
     * @return array
586
     */
587
    public static function reject(array $array, Closure $closure) : array
588
    {
589
        $filtered = [];
590
591
        foreach ($array as $key => $value) {
592
            if ( ! $closure($value, $key)) {
593
                $filtered[$key] = $value;
594
            }
595
        }
596
597
        return $filtered;
598
    }
599
600
    /**
601
     * Remove the first value from an array.
602
     *
603
     * @param array $array
604
     *
605
     * @return array
606
     */
607
    public static function removeFirst(array $array) : array
608
    {
609
        array_shift($array);
610
611
        return $array;
612
    }
613
614
    /**
615
     * Remove the last value from an array.
616
     *
617
     * @param array $array
618
     *
619
     * @return array
620
     */
621
    public static function removeLast(array $array) : array
622
    {
623
        array_pop($array);
624
625
        return $array;
626
    }
627
628
    /**
629
     * Removes a particular value from an array (numeric or associative).
630
     *
631
     * @param array  $array
632
     * @param string $value
633
     *
634
     * @return array
635
     */
636
    public static function removeValue(array $array, string $value) : array
637
    {
638
        $isNumericArray = true;
639
        foreach ($array as $key => $item) {
640
            if ($item === $value) {
641
                if ( ! \is_int($key)) {
642
                    $isNumericArray = false;
643
                }
644
                unset($array[$key]);
645
            }
646
        }
647
        if ($isNumericArray) {
648
            $array = array_values($array);
649
        }
650
651
        return $array;
652
    }
653
654
    /**
655
     * Prepend a value to an array.
656
     *
657
     * @param array  $array
658
     * @param string $value
659
     *
660
     * @return array
661
     */
662
    public static function prepend($array, $value) : array
663
    {
664
        array_unshift($array, $value);
665
666
        return $array;
667
    }
668
669
    /**
670
     * Append a value to an array.
671
     *
672
     * @param array  $array
673
     * @param string $value
674
     *
675
     * @return array
676
     */
677
    public static function append($array, $value) : array
678
    {
679
        $array[] = $value;
680
681
        return $array;
682
    }
683
684
    /*
685
     *  Return a duplicate free copy of an array
686
     * */
687
    /**
688
     * @param array $array
689
     *
690
     * @return array
691
     */
692
    public static function unique($array) : array
693
    {
694
        return array_reduce($array, function($resultArray, $value) {
695
            if ( ! static::contains($resultArray, $value)) {
696
                $resultArray[] = $value;
697
            }
698
699
            return $resultArray;
700
        }, []);
701
    }
702
    //</editor-fold desc="*** Methods ***">
703
}
704