Completed
Push — master ( 892a45...bd3bd3 )
by Radosław
04:37
created

groupBy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace phln\collection;
5
6
use function phln\fn\curryN;
7
8
const groupBy = '\\phln\\collection\\groupBy';
9
const 𝑓groupBy = '\\phln\\collection\\𝑓groupBy';
10
11
/**
12
 * Splits a list into sub-lists stored in an object, based on the result of calling a String-returning function on each element, and grouping the results according to values returned.
13
 *
14
 * @phlnSignature (a -> String) -> [a] -> { String: [a] }
15
 * @phlnCategory collection
16
 * @param callable $fn
17
 * @param array $collection
18
 * @return \Closure|array
19
 * @example
20
 *      \phln\collection\groupBy(
21
 *          function (int $i) {
22
 *              return ($i % 2 === 0)
23
 *                  ? 'even'
24
 *                  : 'odd';
25
 *          },
26
 *          [1, 2, 3, 4]
27
 *      ); // ['odd' => [1, 3], 'even' => [2, 4]]
28
 */
29
function groupBy(callable $fn = null, array $collection = null)
30
{
31
    return curryN(2, 𝑓groupBy, func_get_args());
32
}
33
34
function 𝑓groupBy(callable $fn, array $collection): array
35
{
36
    return reduce(
0 ignored issues
show
Bug Best Practice introduced by
The expression return reduce(function(...., array(), $collection) could return the type Closure which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
37
        function ($carry, $item) use ($fn) {
38
            $key = $fn($item);
39
            $innerList = array_key_exists($key, $carry)
40
                ? $carry[$key]
41
                : [];
42
43
            $carry[$key] = array_merge($innerList, [$item]);
44
45
            return $carry;
46
        },
47
        [],
48
        $collection
49
    );
50
}
51