Passed
Push — master ( 1940b1...c55a2e )
by Pol
03:56
created

Combinate   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
dl 0
loc 71
ccs 27
cts 27
cp 1
rs 10
c 1
b 0
f 0
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getCombinations() 0 17 4
A __construct() 0 3 1
A on() 0 23 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\collection\Operation;
6
7
use Closure;
8
use Generator;
9
use loophp\collection\Contract\Operation;
10
use loophp\collection\Transformation\All;
11
use loophp\collection\Transformation\Count;
12
13
use function array_slice;
14
use function count;
15
16
/**
17
 * Class Combinate.
18
 */
19
final class Combinate implements Operation
20
{
21
    /**
22
     * @var int|null
23
     */
24
    private $length;
25
26
    /**
27
     * Permutations constructor.
28
     *
29
     * @param int $length
30
     */
31 1
    public function __construct(?int $length = null)
32
    {
33 1
        $this->length = $length;
34 1
    }
35
36
    /**
37
     * @param array<mixed> $dataset
38
     * @param int $length
39
     *
40
     * @return Generator<array<mixed>>
41
     */
42 1
    public function getCombinations(array $dataset, int $length): Generator
43
    {
44 1
        $originalLength = count($dataset);
45 1
        $remainingLength = $originalLength - $length + 1;
46
47 1
        for ($i = 0; $i < $remainingLength; ++$i) {
48 1
            $current = $dataset[$i];
49
50 1
            if (1 === $length) {
51 1
                yield [$current];
52
            } else {
53 1
                $remaining = array_slice($dataset, $i + 1);
54
55 1
                foreach ($this->getCombinations($remaining, $length - 1) as $permutation) {
56 1
                    array_unshift($permutation, $current);
57
58 1
                    yield $permutation;
59
                }
60
            }
61
        }
62 1
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 1
    public function on(iterable $collection): Closure
68
    {
69 1
        $length = $this->length;
70
71
        $getPermutation = function (array $dataset, int $length): Generator {
72 1
            return $this->getCombinations($dataset, $length);
73 1
        };
74
75
        return static function () use ($length, $collection, $getPermutation): Generator {
76 1
            $dataset = (new All())->on($collection);
77
78 1
            if (0 < $length) {
79 1
                return yield from $getPermutation($dataset, $length);
80
            }
81
82 1
            $collectionSize = count($dataset);
83
84 1
            if (0 === $length) {
85 1
                return yield from $getPermutation($dataset, $collectionSize);
86
            }
87
88 1
            for ($i = 1; $i <= $collectionSize; ++$i) {
89 1
                yield from $getPermutation($dataset, $i);
90
            }
91 1
        };
92
    }
93
}
94