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.

ArraysMethods::random()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 9
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * This file is part of Underscore.php
6
 *
7
 * (c) Maxime Fabre <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Underscore\Methods;
14
15
use Closure;
16
17
/**
18
 * Methods to manage arrays.
19
 */
20
class ArraysMethods extends CollectionMethods
21
{
22
23
    ////////////////////////////////////////////////////////////////////
24
    ///////////////////////////// GENERATE /////////////////////////////
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|null  $stop  The stopping point
32
     * @param  int  $step  How many to increment of
33
     */
34
    public static function range(int $_base, int $stop = null, int $step = 1) : array
35
    {
36 1
        // Dynamic arguments
37
        if ($stop !== null) {
38
            $start = $_base;
39 1
        } else {
40 1
            $start = 1;
41
            $stop  = $_base;
42
        }
43 1
44 1
        return range($start, $stop, $step);
45
    }
46
47 1
    /**
48
     * Fill an array with $times times some $data.
49
     */
50
    public static function repeat(mixed $data, int $times) : array
51
    {
52
        $timesAbs = abs($times);
53
        if ($timesAbs === 0) {
54
            return [];
55
        }
56
57
        return array_fill(0, $timesAbs, $data);
0 ignored issues
show
Bug introduced by
It seems like $timesAbs can also be of type double; however, parameter $count of array_fill() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

57
        return array_fill(0, /** @scrutinizer ignore-type */ $timesAbs, $data);
Loading history...
58 2
    }
59
60 2
    ////////////////////////////////////////////////////////////////////
61 2
    ///////////////////////////// ANALYZE //////////////////////////////
62
    ////////////////////////////////////////////////////////////////////
63
    /**
64
     * Search for the index of a value in an array.
65 2
     *
66
     * @param  string  $value
67
     *
68
     */
69
    public static function search(array $array, mixed $value) : int|string|bool
70
    {
71
        return array_search($value, $array, true);
72
    }
73
74
    /**
75
     * Check if all items in an array match a truth test.
76
     *
77
     *
78
     */
79
    public static function matches(array $array, callable $closure) : bool
80 1
    {
81
        // Reduce the array to only booleans
82 1
        $array = static::each($array, $closure);
83
84
        // Check the results
85
        if (\count($array) === 0) {
86
            return true;
87
        }
88
89
        $result = array_search(false, $array, false);
90
91
        return \is_bool($result);
92
    }
93 1
94
    /**
95
     * Check if any item in an array matches a truth test.
96 1
     */
97
    public static function matchesAny(array $array, callable $closure) : bool
98
    {
99 1
        // Reduce the array to only booleans
100
        $array = static::each($array, $closure);
101
102 1
        // Check the results
103
        if (\count($array) === 0) {
104 1
            return true;
105
        }
106
107
        $result = array_search(true, $array, false);
108
109
        return \is_int($result);
110
    }
111
112
    /**
113
     * Check if an item is in an array.
114
     *
115 1
     * @param $array
116
     * @param $value
117
     */
118 1
    public static function contains(array $array, mixed $value) : bool
119
    {
120
        return \in_array($value, $array, true);
121 1
    }
122
123
    /**
124 1
     * Returns the average value of an array.
125
     *
126 1
     * @param array $array    The source array
127
     * @param int   $decimals The number of decimals to return
128
     *
129
     * @return float The average value
130
     */
131
    public static function average(array $array, int $decimals = 0) : float
132
    {
133
        return round((array_sum($array) / \count($array)), $decimals);
134
    }
135
136
    /**
137 3
     * Get the size of an array.
138
     */
139 3
    public static function size(array $array) : int
140
    {
141
        return \count($array);
142
    }
143
144
    /**
145
     * Get the max value from an array.
146
     *
147
     * @param  Closure|null  $closure
148
     *
149
     */
150 1
    public static function max(array $array, Closure $closure = null) : mixed
151
    {
152 1
        // If we have a closure, apply it to the array
153
        if ($closure instanceof \Closure) {
154
            $array = static::each($array, $closure);
155
        }
156
157
        return max($array);
158
    }
159
160
    /**
161
     * Get the min value from an array.
162 1
     *
163
     * @param  Closure|null  $closure
164 1
     *
165
     */
166
    public static function min(array $array, Closure $closure = null) : mixed
167
    {
168
        // If we have a closure, apply it to the array
169
        if ($closure instanceof \Closure) {
170
            $array = static::each($array, $closure);
171
        }
172
173
        return min($array);
174
    }
175 2
176
    ////////////////////////////////////////////////////////////////////
177
    //////////////////////////// FETCH FROM ////////////////////////////
178 2
    ////////////////////////////////////////////////////////////////////
179 1
    /**
180
     * Find the first item in an array that passes the truth test.
181
     *
182 2
     * @return mixed|void
183
     */
184
    public static function find(array $array, Closure $closure)
185
    {
186
        foreach ($array as $key => $value) {
187
            if ($closure($value, $key)) {
188
                return $value;
189
            }
190
        }
191
192
        return null;
193 2
    }
194
195
    /**
196 2
     * Clean all falsy values from an array.
197 1
     *
198
     * @return array|mixed
199
     */
200 2
    public static function clean(array $array) : mixed
201
    {
202
        return static::filter($array, fn($value) : bool => (bool) $value);
203
    }
204
205
    /**
206
     * Get a random string from an array.
207
     *
208
     * @param int|null $take
209
     * @return array|mixed
210
     */
211
    public static function random(array $array, int $take = null) : mixed
212
    {
213
        if ($take === null) {
214
            return $array[array_rand($array)];
215 1
        }
216
217 1
        shuffle($array);
218 1
219 1
        return static::first($array, $take);
220
    }
221
222
    /**
223 1
     * Return an array without all instances of certain values.
224
     */
225
    public static function without(...$arguments): mixed
226
    {
227
        $array     = array_shift($arguments);
228
        // if singular argument and is an array treat this AS the array to run without agains
229
        if (\is_array($arguments[0]) && \count($arguments) === 1) {
230
            $arguments = $arguments[0];
231
        }
232
233 1
        return static::filter($array, fn($value) : bool => ! \in_array($value, $arguments, true));
234
    }
235
236 1
    /**
237 1
     * Return an array with all elements found in both input arrays.
238
     */
239
    public static function intersection(array $a, array $b) : array
240
    {
241
        return array_values(array_intersect($a, $b));
242
    }
243
244
    /**
245
     * Return a boolean flag which indicates whether the two input arrays have any common elements.
246
     */
247
    public static function intersects(array $a, array $b) : bool
248 2
    {
249
        return \count(self::intersection($a, $b)) > 0;
250 2
    }
251 1
252
    ////////////////////////////////////////////////////////////////////
253
    ///////////////////////////// SLICERS //////////////////////////////
254 1
    ////////////////////////////////////////////////////////////////////
255
    /**
256 1
     * Get the first value from an array.
257
     *
258
     * @param int|null $take
259
     * @return array|mixed
260
     */
261
    public static function first(array $array, int $take = null) : mixed
262 1
    {
263
        if ($take === null) {
264 1
            return array_shift($array);
265 1
        }
266
267 1
        return array_splice($array, 0, $take, true);
268 1
    }
269
270
    /**
271
     * Get the last value from an array.
272 1
     *
273 1
     * @param int|null $take
274
     * @return array|mixed
275
     */
276
    public static function last(array $array, int $take = null) : mixed
277
    {
278
        if ($take === null) {
279
            return array_pop($array);
280
        }
281
282
        return static::rest($array, -$take);
283
    }
284 2
285
    /**
286 2
     * Get everything but the last $to items.
287 2
     *
288
     *
289 2
     * @return array|mixed
290
     */
291
    public static function initial(array $array, int $to = 1) : mixed
292
    {
293
        $slice = \count($array) - $to;
294
295
        return static::first($array, $slice);
296
    }
297
298
    /**
299
     * Get the last elements from index $from.
300 1
     *
301
     *
302 1
     */
303 1
    public static function rest(array $array, int $from = 1) : array
304
    {
305 1
        return array_splice($array, $from);
306
    }
307
308
    ////////////////////////////////////////////////////////////////////
309
    ///////////////////////////// ACT UPON /////////////////////////////
310
    ////////////////////////////////////////////////////////////////////
311
    /**
312
     * Iterate over an array and execute a callback for each loop.
313
     */
314
    public static function at(array $array, Closure $closure) : array
315
    {
316
        foreach ($array as $key => $value) {
317
            $closure($value, $key);
318
        }
319
320 7
        return $array;
321
    }
322 7
323 5
    ////////////////////////////////////////////////////////////////////
324
    ////////////////////////////// ALTER ///////////////////////////////
325
    ////////////////////////////////////////////////////////////////////
326 3
    /**
327
     * Replace a value in an array.
328
     *
329
     * @param array  $array   The array
330
     * @param string $replace The string to replace
331
     * @param string $with    What to replace it with
332
     */
333
    public static function replaceValue(array $array, string $replace, string $with) : array
334
    {
335
        return static::each($array, fn($value) : string|array => str_replace($replace, $with, (string) $value));
336
    }
337 3
338
    /**
339 3
     * Replace the keys in an array with another set.
340 2
     *
341
     * @param array $array The array
342
     * @param array $keys  An array of keys matching the array's size
343 1
     */
344
    public static function replaceKeys(array $array, array $keys) : array
345
    {
346
        $values = array_values($array);
347
348
        return array_combine($keys, $values);
349
    }
350
351
    /**
352
     * Iterate over an array and modify the array's value.
353
     */
354 1
    public static function each(array $array, Closure $closure) : array
355
    {
356 1
        foreach ($array as $key => $value) {
357
            $array[$key] = $closure($value, $key);
358 1
        }
359
360
        return $array;
361
    }
362
363
    /**
364
     * Shuffle an array.
365
     */
366
    public static function shuffle(array $array) : array
367
    {
368
        shuffle($array);
369 2
370
        return $array;
371 2
    }
372
373
    /**
374
     * Sort an array by key.
375
     */
376
    public static function sortKeys(array $array, string $direction = 'ASC') : array
377
    {
378
        $directionNumber = (strtolower($direction) === 'desc') ? SORT_DESC : SORT_ASC;
379
        if ($directionNumber === SORT_ASC) {
380
            ksort($array);
381
        } else {
382
            krsort($array);
383
        }
384
385
        return $array;
386 1
    }
387
388 1
    /**
389 1
     * Implodes an array.
390
     *
391
     * @param array  $array The array
392 1
     * @param string $with  What to implode it with
393
     */
394
    public static function implode(array $array, string $with = '') : string
395
    {
396
        return implode($with, $array);
397
    }
398
399
    /**
400
     * Find all items in an array that pass the truth test.
401
     *
402
     * @param  Closure|null  $closure
403
     * @return array|mixed
404
     */
405
    public static function filter(array $array, Closure $closure = null) : mixed
406
    {
407
        if ( ! $closure instanceof \Closure) {
408 1
            return static::clean($array);
409
        }
410
411 1
        return array_filter($array, $closure);
412 1
    }
413
414
    /**
415
     * Flattens an array to dot notation.
416
     *
417
     * @param  array  $array  An array
418
     * @param  string  $separator  The characater to flatten with
419
     * @param  string|null  $parent  The parent passed to the child (private)
420
     *
421
     * @return array Flattened array to one level
422
     */
423 1
    public static function flatten(array $array, string $separator = '.', string $parent = null) : array
424
    {
425 1
        $_flattened = [];
426
427 1
        // Rewrite keys
428
        foreach ($array as $key => $value) {
429
            if ($parent) {
430
                $key = $parent.$separator.$key;
431
            }
432
433
            if ( ! \is_array($value)) {
434
                $_flattened[$key] = $value;
435
                continue;
436
            }
437
438 8
            $_flattened[$key] = static::flatten($value, $separator, $key);
439
        }
440 8
441 8
        // Flatten
442
        $flattened = [];
443
        foreach ($_flattened as $key => $value) {
444 8
            if (\is_array($value)) {
445
                $flattened = [...$flattened, ...$value];
446
            } else {
447
                $flattened[$key] = $value;
448
            }
449
        }
450
451
        return $flattened;
452
    }
453
454
    /**
455
     * Invoke a function on all of an array's values.
456
     *
457
     * @param  Closure|string  $callable  $callable
458
     * @param  array  $arguments
459
     *
460
     */
461
    public static function invoke(array $array, Closure|string $callable, mixed $arguments = []) : array
462
    {
463
        // If one argument given for each iteration, create an array for it
464
        if ( ! \is_array($arguments)) {
465
            $arguments = static::repeat($arguments, \count($array));
466
        }
467
468
        // If the callable has arguments, pass them
469 1
        if ($arguments) {
470
            return array_map($callable, $array, $arguments);
471 1
        }
472 1
473 1
        return array_map($callable, $array);
474
    }
475
476 1
    /**
477
     * Return all items that fail the truth test.
478
     */
479 1
    public static function reject(array $array, Closure $closure) : array
480
    {
481
        $filtered = [];
482
483
        foreach ($array as $key => $value) {
484
            if ( ! $closure($value, $key)) {
485
                $filtered[$key] = $value;
486
            }
487
        }
488
489
        return $filtered;
490 2
    }
491
492 2
    /**
493
     * Remove the first value from an array.
494
     */
495
    public static function removeFirst(array $array) : array
496
    {
497
        array_shift($array);
498
499
        return $array;
500
    }
501
502
    /**
503 4
     * Remove the last value from an array.
504
     */
505 4
    public static function removeLast(array $array) : array
506
    {
507
        array_pop($array);
508
509 4
        return $array;
510
    }
511
512
    /**
513
     * Removes a particular value from an array (numeric or associative).
514
     */
515
    public static function removeValue(array $array, string $value) : array
516
    {
517
        $isNumericArray = true;
518
        foreach ($array as $key => $item) {
519
            if ($item === $value) {
520
                if ( ! \is_int($key)) {
521 2
                    $isNumericArray = false;
522
                }
523 2
524
                unset($array[$key]);
525
            }
526 2
        }
527 2
528 2
        if ($isNumericArray) {
529
            return array_values($array);
530 2
        }
531 2
532 2
        return $array;
533
    }
534 2
535
    /**
536
     * Prepend a value to an array.
537
     *
538 2
     * @param  string  $value
539 2
     *
540 2
     */
541 2
    public static function prepend(array $array, mixed $value) : array
542
    {
543
        array_unshift($array, $value);
544 2
545
        return $array;
546
    }
547
548 2
    /**
549
     * Append a value to an array.
550
     *
551
     * @param string $value
552
     */
553
    public static function append(array $array, mixed $value) : array
554
    {
555
        $array[] = $value;
556
557
        return $array;
558
    }
559
560 3
    /**
561
     * Return a duplicate free copy of an array
562
     *
563 3
     *
564 1
     */
565
    public static function unique(array $array) : array
566
    {
567
        return array_reduce($array, function (array $resultArray, $value) : array {
568 3
            if ( ! static::contains($resultArray, $value)) {
569 2
                $resultArray[] = $value;
570
            }
571
572 1
            return $resultArray;
573
        }, []);
574
    }
575
576
    //</editor-fold desc="*** Methods ***">
577
}
578