zip()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 1
nop 2
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Array functions.
5
 *
6
 * This file is part of PinkCrab Function Constructors.
7
 *
8
 * PinkCrab Function Constructors is free software: you can redistribute it and/or modify it under the terms of the
9
 * GNU General Public License as published by the Free Software Foundation, either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * PinkCrab Function Constructors is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
13
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with PinkCrab Function Constructors.
17
 * If not, see <https://www.gnu.org/licenses/>.
18
 *
19
 * @author Glynn Quelch <[email protected]>
20
 * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
21
 * @package PinkCrab\FunctionConstructors
22
 * @since 0.0.1
23
 *
24
 * @template Number of int|float
25
 * @phpstan-template Number of int|float
26
 * @psalm-template Number of int|float
27
 */
28
29
declare(strict_types=1);
30
31
namespace PinkCrab\FunctionConstructors\Arrays;
32
33
use Closure;
34
use stdClass;
35
use PinkCrab\FunctionConstructors\Comparisons as Comp;
1 ignored issue
show
Bug introduced by
The type PinkCrab\FunctionConstructors\Comparisons was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
37
/**
38
 * Returns a Closure for pushing a value to the head of an array
39
 *
40
 * @param array<int|string, mixed> $array
41
 * @return Closure(mixed):array<int|string, mixed>
42
 */
43
function pushHead(array $array): Closure
44
{
45
    /**
46
     * @param mixed $value Adds value start of array.
47
     * @return array New array with value on head.
48
     */
49
    return function ($value) use ($array): array {
50
        array_unshift($array, $value);
51
        return $array;
52
    };
53
}
54
55
/**
56
 * Returns a Closure for pushing a value to the head of an array
57
 *
58
 * @param array<int|string, mixed> $array
59
 * @return Closure(mixed):array<int|string, mixed>
60
 */
61
function pushTail(array $array): Closure
62
{
63
    /**
64
     * @param mixed $value Adds value end of array.
65
     * @return array<int|string, mixed> New array with value on tail.
66
     */
67
    return function ($value) use ($array): array {
68
        $array[] = $value;
69
        return $array;
70
    };
71
}
72
73
/**
74
 * Gets the first value from an array.
75
 *
76
 * @param array<int|string, mixed> $array The array.
77
 * @return mixed Will return the first value is array is not empty, else null.
78
 */
79
function head(array $array)
80
{
81
    return ! empty($array) ? array_values($array)[0] : null;
82
}
83
84
/**
85
 * Gets the last value from an array.
86
 *
87
 * @param array<int|string, mixed> $array
88
 * @return mixed Will return the last value is array is not empty, else null.
89
 */
90
function tail(array $array)
91
{
92
    return ! empty($array) ? array_reverse($array, false)[0] : null;
93
}
94
95
96
/**
97
 * Creates a Closure for concatenating arrays with a defined glue.
98
 *
99
 * @param string|null $glue The string to join each element. If null, will be no separation between elements.
100
 * @return Closure(array<int|string, mixed>):string
101
 *
102
 */
103
function toString(?string $glue = null): Closure
104
{
105
    /**
106
     * @param array<int|string, mixed> $array Array join
107
     * @return string.
108
     */
109
    return function (array $array) use ($glue): string {
110
        return $glue ? \join($glue, $array) : \join($array);
1 ignored issue
show
Bug introduced by
The call to join() has too few arguments starting with array. ( Ignorable by Annotation )

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

110
        return $glue ? \join($glue, $array) : /** @scrutinizer ignore-call */ \join($array);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
111
    };
112
}
113
114
/**
115
 * Creates a Closure for zipping 2 arrays.
116
 *
117
 * @param array<mixed> $additional Values with the same key will be paired.
118
 * @param mixed $default The fallback value if the additional array doesn't have the same length
119
 * @return Closure(array<mixed>):array<array{mixed, mixed}>
120
 *
121
 */
122
function zip(array $additional, $default = null): Closure
123
{
124
    $additional = array_values($additional);
125
    return function (array $array) use ($additional, $default) {
126
        $array = array_values($array);
127
        return array_reduce(
128
            array_keys($array),
129
            function ($carry, $key) use ($array, $additional, $default): array {
130
                $carry[] = array(
131
                    $array[ $key ],
132
                    array_key_exists($key, $additional) ? $additional[ $key ] : $default,
133
                );
134
                return $carry;
135
            },
136
            array()
137
        );
138
    };
139
}
140
141
142
/*
143
 *                                ********************
144
 *                                * Filter Compilers *
145
 *                                ********************
146
 */
147
148
149
/**
150
 * Compiles an array if a value is passed.
151
 * Returns the array if nothing passed.
152
 *
153
 * @param mixed[] $inital Sets up the inner value.
154
 * @return Closure
155
 */
156
function arrayCompiler(array $inital = array()): Closure
157
{
158
    /**
159
     * @param mixed $value Adds value to inner array if value set, else returns.
160
     * @return mixed[]|Closure
161
     */
162
    return function ($value = null) use ($inital) {
163
        if ($value) {
164
            $inital[] = $value;
165
        }
166
        return ! is_null($value) ? arrayCompiler($inital) : $inital;
167
    };
168
}
169
170
/**
171
 * Creates a typed array compiler.
172
 * All values which do not pass the validator are not added.
173
 *
174
 * @param Closure(mixed):bool $validator Used to validate values before adding to array.
175
 * @param mixed[] $inital The inital data to start with
176
 * @return Closure
177
 */
178
function arrayCompilerTyped(callable $validator, array $inital = array()): Closure
179
{
180
    // Ensure all is validated from initial.
181
    $inital = array_filter($inital, $validator);
182
183
    /**
184
     * @param mixed $value
185
     * @return mixed[]|Closure
186
     */
187
    return function ($value = null) use ($validator, $inital) {
188
        if (! is_null($value) && $validator($value)) {
189
            $inital[] = $value;
190
        }
191
        return ! is_null($value) ? arrayCompilerTyped($validator, $inital) : $inital;
192
    };
193
}
194
195
196
197
/*
198
 *                                ********************
199
 *                                * Filter Functions *
200
 *                                ********************
201
 */
202
203
204
/**
205
 * Created a Closure for filtering an array.
206
 *
207
 * @param callable $callable The function to apply to the array.
208
 * @return Closure(array<int|string, mixed>):array<int|string, mixed>
209
 */
210
function filter(callable $callable): Closure
211
{
212
    /**
213
     * @param array<int|string, mixed> $source Array to filter
214
     * @return array<int|string, mixed> Filtered array.
215
     */
216
    return function (array $source) use ($callable): array {
217
        return array_filter($source, $callable);
218
    };
219
}
220
221
/**
222
 * Create a Closure for filtering an array by a key.
223
 *
224
 * @param callable $callable The function to apply to the array.
225
 * @return Closure(array<int|string, mixed>):array<int|string, mixed>
226
 */
227
function filterKey(callable $callable): Closure
228
{
229
    /**
230
     * @param array<int|string, mixed> $source Array to filter
231
     * @return array<int|string, mixed> Filtered array.
232
     */
233
    return function (array $source) use ($callable): array {
234
        return array_filter($source, $callable, \ARRAY_FILTER_USE_KEY);
235
    };
236
}
237
238
239
/**
240
 * Creates a Closure for running an array through various callbacks for all true response.
241
 * Wrapper for creating a AND group of callbacks and running through array filter.
242
 *
243
 * @param callable ...$callables
244
 * @return Closure(array<int|string, mixed>):array<int|string, mixed>
245
 */
246
function filterAnd(callable ...$callables): Closure
247
{
248
    /**
249
     * @param array<int|string, mixed> $source Array to filter
250
     * @return array<int|string, mixed> Filtered array.
251
     */
252
    return function (array $source) use ($callables): array {
253
        return array_filter($source, Comp\groupAnd(...$callables));
1 ignored issue
show
Bug introduced by
The function groupAnd was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

253
        return array_filter($source, /** @scrutinizer ignore-call */ Comp\groupAnd(...$callables));
Loading history...
254
    };
255
}
256
257
/**
258
 * Creates a Closure for running an array through various callbacks for any true response.
259
 * Wrapper for creating a OR group of callbacks and running through array filter.
260
 *
261
 * @param callable ...$callables
262
 * @return Closure(array<int|string, mixed>):array<int|string, mixed>
263
 */
264
function filterOr(callable ...$callables): Closure
265
{
266
    /**
267
     * @param array<int|string, mixed> $source Array to filter
268
     * @return array<int|string, mixed> Filtered array.
269
     */
270
    return function (array $source) use ($callables): array {
271
        return array_filter($source, Comp\groupOr(...$callables));
1 ignored issue
show
Bug introduced by
The function groupOr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

271
        return array_filter($source, /** @scrutinizer ignore-call */ Comp\groupOr(...$callables));
Loading history...
272
    };
273
}
274
275
/**
276
 * Creates a Closure for running array filter and getting the first value.
277
 *
278
 * @param callable $func
279
 * @return Closure(array<int|string, mixed>):?mixed
280
 */
281
function filterFirst(callable $func): Closure
282
{
283
    /**
284
     * @param array<int|string, mixed> $array The array to filter
285
     * @return mixed|null The first element from the filtered array or null if filter returns empty
286
     */
287
    return function (array $array) use ($func) {
288
        return head(array_filter($array, $func));
289
    };
290
}
291
292
/**
293
 * Creates a Closure for running array filter and getting the last value.
294
 *
295
 * @param callable $func
296
 * @return Closure(array<int|string, mixed>):?mixed
297
 */
298
function filterLast(callable $func): Closure
299
{
300
    /**
301
     * @param array<int|string, mixed> $array The array to filter
302
     * @return mixed|null The last element from the filtered array.
303
     */
304
    return function (array $array) use ($func) {
305
        return tail(array_filter($array, $func));
306
    };
307
}
308
309
/**
310
 * Creates a Closure which takes an array, applies a filter, then maps the
311
 * results of the map.
312
 *
313
 *
314
 * @param callable(mixed):bool $filter Function to of filter contents
315
 * @param callable(mixed):mixed $map Function to map results of filter function.
316
 * @return Closure(array<int|string, mixed>):array<int|string, mixed>
317
 */
318
function filterMap(callable $filter, callable $map): Closure
319
{
320
    /**
321
     * @param array<int|string, mixed> $array The array to filter then map.
322
     * @return array<int|string, mixed>
323
     */
324
    return function (array $array) use ($filter, $map): array {
325
        return array_map($map, array_filter($array, $filter));
326
    };
327
}
328
329
/**
330
 * Runs an array through a filters, returns the total count of true
331
 *
332
 * @param callable $function
333
 * @return Closure(array<int|string, mixed>):int
334
 */
335
function filterCount(callable $function): Closure
336
{
337
    /**
338
     * @param array<int|string, mixed> $array
339
     * @return int Count
340
     */
341
    return function (array $array) use ($function) {
342
        return count(array_filter($array, $function));
343
    };
344
}
345
346
/**
347
 * Returns a Closure for partitioning an array based
348
 * on the results of a filter type function.
349
 * Callable will be cast to a bool, if truthy will be listed under 1 key, else 0 for falsey
350
 *
351
 * @param callable(mixed):(bool|int) $function
352
 * @return Closure(mixed[]):array{0:mixed[], 1:mixed[]}
353
 */
354
function partition(callable $function): Closure
355
{
356
    /**
357
     * @param mixed[] $array
358
     * @return array{0:mixed[], 1:mixed[]}
359
     */
360
    return function (array $array) use ($function): array {
361
        return array_reduce(
362
            $array,
363
            /**
364
             * @param array{0:mixed[], 1:mixed[]} $carry
365
             * @param mixed $element
366
             * @return array{0:mixed[], 1:mixed[]}
367
             */
368
            function ($carry, $element) use ($function): array {
369
                $key             = (bool) $function($element) ? 1 : 0;
370
                $carry[ $key ][] = $element;
371
                return $carry;
372
            },
373
            array( array(), array() )
374
        );
375
    };
376
}
377
378
379
380
381
382
/*
383
 *                           *****************
384
 *                           * Map Functions *
385
 *                           *****************
386
 */
387
388
389
390
/**
391
 * Returns a Closure which can be passed an array.
392
 *
393
 * @param callable(mixed):mixed $func Callback to apply to each element in array.
394
 * @return Closure(mixed[]):mixed[]
395
 */
396
function map(callable $func): Closure
397
{
398
    /**
399
     * @param mixed[] $array The array to map
400
     * @return mixed[]
401
     */
402
    return function (array $array) use ($func): array {
403
        return array_map($func, $array);
404
    };
405
}
406
407
/**
408
 * Returns a Closure for mapping of an arrays keys.
409
 * Setting the key to an existing index will overwrite the current value at same index.
410
 *
411
 * @param callable $func
412
 * @return Closure(mixed[]):mixed[]
413
 */
414
function mapKey(callable $func): Closure
415
{
416
    /**
417
     * @param mixed[] $array The array to map
418
     * @return mixed[]
419
     */
420
    return function (array $array) use ($func): array {
421
        return array_reduce(
422
            array_keys($array),
423
            function ($carry, $key) use ($func, $array) {
424
                $carry[ $func($key) ] = $array[ $key ];
425
                return $carry;
426
            },
427
            array()
428
        );
429
    };
430
}
431
432
/**
433
 * Returns a Closure for mapping an array with additional data.
434
 *
435
 * @param callable(mixed ...$a):mixed $func
436
 * @param mixed ...$data
437
 * @return Closure(mixed[]):mixed[]
438
 */
439
function mapWith(callable $func, ...$data): Closure
440
{
441
    /**
442
     * @param mixed[] $array The array to map
443
     * @return mixed[]
444
     */
445
    return function (array $array) use ($func, $data): array {
446
        return array_map(
447
            function ($e) use ($data, $func) {
448
                return $func($e, ...$data);
449
            },
450
            $array
451
        );
452
    };
453
}
454
455
/**
456
 * Returns a Closure for flattening and mapping an array
457
 *
458
 * @param callable(mixed):mixed $function The function to map the element. (Will no be called if resolves to array)
459
 * @param int|null $n Depth of nodes to flatten. If null will flatten to n
460
 * @return Closure(mixed[]):mixed[]
461
 */
462
function flatMap(callable $function, ?int $n = null): Closure
463
{
464
    /**
465
     * @param mixed[] $array
466
     * @return mixed[]
467
     */
468
    return function (array $array) use ($n, $function): array {
469
        return array_reduce(
470
            $array,
471
            /**
472
             * @param mixed[] $carry
473
             * @param mixed $element
474
             * @return mixed[]
475
             */
476
            function (array $carry, $element) use ($n, $function): array {
477
                if (is_array($element) && (is_null($n) || $n > 0)) {
478
                    $carry = array_merge($carry, flatMap($function, $n ? $n - 1 : null)($element));
479
                } else {
480
                    $carry[] = is_array($element) ? $element : $function($element);
481
                }
482
                return $carry;
483
            },
484
            array()
485
        );
486
    };
487
}
488
489
/*
490
 *                         **********************
491
 *                         * General Operations *
492
 *                         **********************
493
 */
494
495
496
/**
497
 * Creates a Closure for grouping an array.
498
 *
499
 * @param callable(mixed):(string|int) $function The function to group by.
500
 * @return Closure(mixed):mixed[]
501
 */
502
function groupBy(callable $function): Closure
503
{
504
    /**
505
     * @param mixed[] $array The array to be grouped
506
     * @return mixed[] Grouped array.
507
     */
508
    return function (array $array) use ($function): array {
509
        return array_reduce(
510
            $array,
511
            /**
512
             * @param mixed[] $carry
513
             * @param mixed $element
514
             * @return mixed[]
515
             */
516
            function ($carry, $item) use ($function): array {
517
                $carry[ call_user_func($function, $item) ][] = $item;
518
                return $carry;
519
            },
520
            array()
521
        );
522
    };
523
}
524
525
/**
526
 * Creates a Closure for chunking an array to set a limit.
527
 *
528
 * @param int $count The max size of each chunk. Must not be less than 1!
529
 * @param bool $preserveKeys Should inital keys be kept. Default false.
530
 * @return Closure(mixed[]):mixed[]
531
 */
532
function chunk(int $count, bool $preserveKeys = false): Closure
533
{
534
    /**
535
     * @param mixed[] $array Array to chunk
536
     * @return mixed[]
537
     */
538
    return function (array $array) use ($count, $preserveKeys): array {
539
        return array_chunk($array, max(1, $count), $preserveKeys);
540
    };
541
}
542
543
/**
544
 * Create callback for extracting a single column from an array.
545
 *
546
 * @param string $column Column to retrieve.
547
 * @param string $key Use column for assigning as the index. defaults to numeric keys if null.
548
 * @return Closure(mixed[]):mixed[]
549
 */
550
function column(string $column, ?string $key = null): Closure
551
{
552
    /**
553
     * @param mixed[] $array
554
     * @return mixed[]
555
     */
556
    return function (array $array) use ($column, $key): array {
557
        return array_column($array, $column, $key);
558
    };
559
}
560
561
/**
562
 * Returns a Closure for flattening an array to a defined depth
563
 *
564
 * @param int|null $n Depth of nodes to flatten. If null will flatten to n
565
 * @return Closure(mixed[] $var): mixed[]
566
 */
567
function flattenByN(?int $n = null): Closure
568
{
569
    /**
570
     * @param mixed[] $array Array to flatten
571
     * @return mixed[]
572
     */
573
    return function (array $array) use ($n): array {
574
        return array_reduce(
575
            $array,
576
            /**
577
             * @param array<int|string, mixed> $carry
578
             * @param mixed|mixed[] $element
579
             * @return array<int|string, mixed>
580
             */
581
            function (array $carry, $element) use ($n): array {
582
                // Remove empty arrays.
583
                if (is_array($element) && empty($element)) {
584
                    return $carry;
585
                }
586
                // If the element is an array and we are still flattening, call again
587
                if (is_array($element) && (is_null($n) || $n > 0)) { // @phpstan-ignore-line
588
                    $carry = array_merge($carry, flattenByN($n ? $n - 1 : null)($element));
589
                } else {
590
                    // Else just add the element.
591
                    $carry[] = $element;
592
                }
593
                return $carry;
594
            },
595
            array()
596
        );
597
    };
598
}
599
600
/**
601
 * Returns a closure for recursively changing values in an array.
602
 *
603
 * @param mixed[] ...$with The array values to replace with
604
 * @return Closure(mixed[]):mixed[]
605
 */
606
function replaceRecursive(array ...$with): Closure
607
{
608
    /**
609
     * @param mixed[] $array The array to have elements replaced from.
610
     * @return mixed[] Array with replacements.
611
     */
612
    return function (array $array) use ($with): array {
613
        return array_replace_recursive($array, ...$with);
614
    };
615
}
616
617
/**
618
 * Returns a Closure for changing all values in a flat array, based on key.
619
 *
620
 * @param mixed[] ...$with Array with values to replace with, must have matching key with base array.
621
 * @return Closure(mixed[]):mixed[]
622
 */
623
function replace(array ...$with): Closure
624
{
625
    /**
626
     * @param mixed[] $array The array to have elements replaced from.
627
     * @return mixed[] Array with replacements.
628
     */
629
    return function (array $array) use ($with): array {
630
        return array_replace($array, ...$with);
631
    };
632
}
633
634
/**
635
 * Returns a Closure for doing array_sum with the results of a function/expression.
636
 *
637
 * @param callable(mixed):Number $function The function to return the value for array sum
638
 * @return Closure(mixed[]):Number
639
 */
640
function sumWhere(callable $function): Closure
641
{
642
    /**
643
     * @param mixed[] $array Array to do sum() on.
644
     * @return Number The total.
645
     */
646
    return function (array $array) use ($function) {
647
        return array_sum(array_map($function, $array));
648
    };
649
}
650
651
/**
652
 * Creates a closure for casting an array to an object.
653
 * Assumed all properties are public
654
 * None existing properties will be set as dynamic properties.
655
 *
656
 * @param object|null $object The object to cast to, defaults to stdClass
657
 * @return Closure(mixed[]):object
658
 */
659
function toObject(?object $object = null): Closure
660
{
661
    $object = $object ?? new stdClass();
662
663
    /**
664
     * @param mixed[] $array
665
     * @return object
666
     */
667
    return function (array $array) use ($object): object {
668
        foreach ($array as $key => $value) {
669
            $key            = is_string($key) ? $key : (string) $key;
670
            $object->{$key} = $value;
671
        }
672
        return $object;
673
    };
674
}
675
676
/**
677
 * Creates a closure for encoding json with defined flags/depth
678
 *
679
 * @param int $flags json_encode flags (default = 0)
680
 * @param int $depth Nodes deep to encode (default = 512)
681
 * @return \Closure(mixed):?string
682
 * @constants JSON_FORCE_OBJECT, JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP,
683
 *            JSON_HEX_APOS, JSON_INVALID_UTF8_IGNORE,
684
 *            JSON_INVALID_UTF8_SUBSTITUTE, JSON_NUMERIC_CHECK,
685
 *            JSON_PARTIAL_OUTPUT_ON_ERROR, JSON_PRESERVE_ZERO_FRACTION,
686
 *            JSON_PRETTY_PRINT, JSON_UNESCAPED_LINE_TERMINATORS,
687
 *            JSON_UNESCAPED_SLASHES, JSON_UNESCAPED_UNICODE, JSON_THROW_ON_ERROR
688
 */
689
function toJson(int $flags = 0, int $depth = 512): Closure
690
{
691
    /**
692
     * @param mixed $data
693
     * @return string|null
694
     */
695
    return function ($data) use ($flags, $depth): ?string {
696
        return \json_encode($data, $flags, max(1, $depth)) ?: null;
697
    };
698
}
699
700
701
/*
702
 *                         ****************
703
 *                         *  Array Sort  *
704
 *                         ****************
705
 */
706
707
708
/**
709
 * Returns a Closure for doing regular SORT against an array.
710
 * Doesn't maintain keys.
711
 *
712
 * @param int $flag Uses php stock sort constants or numerical values.
713
 * @return Closure(mixed[]):mixed[]
714
 */
715
function sort(int $flag = SORT_REGULAR): Closure
716
{
717
    /**
718
     *  @param mixed[]$array The array to sort
719
     *  @return mixed[] The sorted array (new array)
720
     */
721
    return function (array $array) use ($flag) {
722
        \sort($array, $flag);
723
        return $array;
724
    };
725
}
726
727
/**
728
 * Returns a Closure for doing regular Reverse SORT against an array.
729
 * Doesn't maintain keys.
730
 *
731
 * @param int $flag Uses php stock sort constants or numerical values.
732
 * @return Closure(mixed[]):mixed[]
733
 */
734
function rsort(int $flag = SORT_REGULAR): Closure
735
{
736
    /**
737
     *  @param mixed[]$array The array to sort
738
     *  @return mixed[] The sorted array (new array)
739
     */
740
    return function (array $array) use ($flag) {
741
        \rsort($array, $flag);
742
        return $array;
743
    };
744
}
745
746
747
/**
748
 * Returns a Closure for sorting an array by key in ascending order.
749
 *
750
 * @param int $flag Uses php stock sort constants or numerical values.
751
 * @return Closure(mixed[]):mixed[]
752
 */
753
function ksort(int $flag = SORT_REGULAR): Closure
754
{
755
    /**
756
     *  @param mixed[]$array The array to sort
757
     *  @return mixed[] The sorted array (new array)
758
     */
759
    return function (array $array) use ($flag) {
760
        \ksort($array, $flag);
761
        return $array;
762
    };
763
}
764
765
/**
766
 * Returns a Closure for sorting an array by key in descending (reverse) order.
767
 *
768
 * @param int $flag Uses php stock sort constants or numerical values.
769
 * @return Closure(mixed[]):mixed[]
770
 */
771
function krsort(int $flag = SORT_REGULAR): Closure
772
{
773
    /**
774
     *  @param mixed[]$array The array to sort
775
     *  @return mixed[] The sorted array (new array)
776
     */
777
    return function (array $array) use ($flag) {
778
        \krsort($array, $flag);
779
        return $array;
780
    };
781
}
782
783
/**
784
 * Returns a Closure for sorting an array by value in ascending order.
785
 * Maintain keys.
786
 *
787
 * @param int $flag Uses php stock sort constants or numerical values.
788
 * @return Closure(mixed[]):mixed[]
789
 */
790
function asort(int $flag = SORT_REGULAR): Closure
791
{
792
    /**
793
     *  @param mixed[]$array The array to sort
794
     *  @return mixed[] The sorted array (new array)
795
     */
796
    return function (array $array) use ($flag) {
797
        \asort($array, $flag);
798
        return $array;
799
    };
800
}
801
802
/**
803
 * Returns a Closure for sorting an array by value in descending (reverse) order.
804
 * Maintain keys.
805
 *
806
 * @param int $flag Uses php stock sort constants or numerical values.
807
 * @return Closure(mixed[]):mixed[]
808
 */
809
function arsort(int $flag = SORT_REGULAR): Closure
810
{
811
    /**
812
     *  @param mixed[]$array The array to sort
813
     *  @return mixed[] The sorted array (new array)
814
     */
815
    return function (array $array) use ($flag) {
816
        \arsort($array, $flag);
817
        return $array;
818
    };
819
}
820
821
/**
822
 * Returns a Closure for sorting an array using a "natural order" algorithm
823
 *
824
 * @return Closure(mixed[]):mixed[]
825
 */
826
function natsort(): Closure
827
{
828
    /**
829
     *  @param mixed[]$array The array to sort
830
     *  @return mixed[] The sorted array (new array)
831
     */
832
    return function (array $array) {
833
        \natsort($array);
834
        return $array;
835
    };
836
}
837
838
/**
839
 * Returns a Closure for sorting an array using a case insensitive "natural order" algorithm
840
 *
841
 * @return Closure(mixed[]):mixed[]
842
 */
843
function natcasesort(): Closure
844
{
845
    /**
846
     *  @param mixed[]$array The array to sort
847
     *  @return mixed[] The sorted array (new array)
848
     */
849
    return function (array $array) {
850
        \natcasesort($array);
851
        return $array;
852
    };
853
}
854
855
/**
856
 * Returns a Closure for sorting an array by key using a custom comparison function
857
 *
858
 * @param callable(mixed $a, mixed $b): int $function
859
 * @return Closure(mixed[]):mixed[]
860
 */
861
function uksort(callable $function): Closure
862
{
863
    /**
864
     *  @param mixed[] $array The array to sort
865
     *  @return mixed[] The sorted array (new array)
866
     */
867
    return function (array $array) use ($function) {
868
        \uksort($array, $function);
869
        return $array;
870
    };
871
}
872
873
/**
874
 * Returns a Closure for sorting an array using a custom comparison function
875
 * Maintain keys.
876
 *
877
 * @param callable(mixed $a, mixed $b): int $function
878
 * @return Closure(mixed[]):mixed[]
879
 */
880
function uasort(callable $function): Closure
881
{
882
    /**
883
     *  @param mixed[]$array The array to sort
884
     *  @return mixed[] The sorted array (new array)
885
     */
886
    return function (array $array) use ($function) {
887
        \uasort($array, $function);
888
        return $array;
889
    };
890
}
891
892
893
/**
894
 * Returns a Closure for sorting an array using a custom comparison function
895
 * Doesn't maintain keys.
896
 *
897
 * @param callable(mixed $a, mixed $b): int $function
898
 * @return Closure(mixed[]):mixed[]
899
 */
900
function usort(callable $function): Closure
901
{
902
    /**
903
     *  @param mixed[]$array The array to sort
904
     *  @return mixed[] The sorted array (new array)
905
     */
906
    return function (array $array) use ($function) {
907
        \usort($array, $function);
908
        return $array;
909
    };
910
}
911