Combinate::__invoke()   B
last analyzed

Complexity

Conditions 7
Paths 1

Size

Total Lines 48
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 20
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 48
ccs 22
cts 22
cp 1
crap 7
rs 8.6666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\collection\Operation;
6
7
use Closure;
8
use Generator;
9
10
use function array_slice;
11
use function count;
12
13
/**
14
 * @immutable
15
 *
16
 * @template TKey
17
 * @template T
18
 */
19
final class Combinate extends AbstractOperation
20
{
21 6
    public function __invoke(): Closure
22
    {
23 6
        return static function (?int $length = null): Closure {
24 6
            $getCombinations =
25
                /**
26
                 * @param array<int, T> $dataset
27
                 *
28
                 * @return Generator<array<int, T>>
29
                 */
30 6
                static function (array $dataset, int $length) use (&$getCombinations): Generator {
31 6
                    for ($i = 0; count($dataset) - $length >= $i; ++$i) {
32 6
                        if (1 === $length) {
33 6
                            yield [$dataset[$i]];
34
35 6
                            continue;
36
                        }
37
38
                        /** @var array<int, T> $permutation */
39 4
                        foreach ($getCombinations(array_slice($dataset, $i + 1), $length - 1) as $permutation) {
40 4
                            array_unshift($permutation, $dataset[$i]);
41
42 4
                            yield $permutation;
43
                        }
44
                    }
45 6
                };
46
47 6
            return
48
                /**
49
                 * @param iterable<TKey, T> $iterable
50
                 *
51
                 * @return Generator<int, array<int, T>>
52
                 */
53 6
                static function (iterable $iterable) use ($length, $getCombinations): Generator {
54
                    /** @psalm-suppress InvalidOperand */
55 6
                    $dataset = [...$iterable];
56
57 6
                    if (0 < $length) {
58 2
                        return yield from $getCombinations($dataset, $length);
59
                    }
60
61 4
                    $collectionSize = count($dataset);
62
63 4
                    if (0 === $length) {
64 2
                        return yield from $getCombinations($dataset, $collectionSize);
65
                    }
66
67 2
                    for ($i = 1; $i <= $collectionSize; ++$i) {
68 2
                        yield from $getCombinations($dataset, $i);
69
                    }
70 6
                };
71 6
        };
72
    }
73
}
74