Combinations   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 14
eloc 28
c 3
b 0
f 0
dl 0
loc 109
ccs 35
cts 35
cp 1
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A nextHelper() 0 19 5
A next() 0 6 2
A rewind() 0 4 1
A valid() 0 3 1
A current() 0 9 2
A __construct() 0 4 1
A count() 0 9 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace drupol\phpermutations\Iterators;
6
7
use drupol\phpermutations\Iterators;
8
9
class Combinations extends Iterators
10
{
11
    /**
12
     * The values.
13
     *
14
     * @var array<int, mixed>
15
     */
16
    protected $c = [];
17
18
    /**
19
     * Combinations constructor.
20
     *
21
     * @param array<int, mixed> $dataset
22
     *                          The dataset
23
     * @param int|null $length
24
     *                          The length
25
     */
26 5
    public function __construct(array $dataset = [], $length = null)
27
    {
28 5
        parent::__construct(array_values($dataset), $length);
29 5
        $this->rewind();
30 5
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35 5
    public function count(): int
36
    {
37 5
        $i = 0;
38
39 5
        for ($this->rewind(); $this->valid(); $this->next()) {
40 5
            ++$i;
41
        }
42
43 5
        return $i;
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 5
    public function current(): mixed
50
    {
51 5
        $r = [];
52
53 5
        for ($i = 0; $i < $this->length; ++$i) {
54 5
            $r[] = $this->dataset[$this->c[$i]];
55
        }
56
57 5
        return $r;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     *
63
     * @return void
64
     */
65 5
    public function next(): void
66
    {
67 5
        if ($this->nextHelper()) {
68 4
            ++$this->key;
69
        } else {
70 5
            $this->key = -1;
71
        }
72 5
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 5
    public function rewind(): void
78
    {
79 5
        $this->c = range(0, $this->length);
80 5
        $this->key = 0;
81 5
    }
82
83
    /**
84
     * {@inheritdoc}
85
     *
86
     * @return bool
87
     */
88 5
    public function valid(): bool
89
    {
90 5
        return 0 <= $this->key;
91
    }
92
93
    /**
94
     * Custom next() callback.
95
     *
96
     * @return bool
97
     *              Return true or false
98
     */
99 5
    protected function nextHelper(): bool
100
    {
101 5
        $i = $this->length - 1;
102
103 5
        while (0 <= $i && $this->datasetCount - $this->length + $i === $this->c[$i]) {
104 5
            --$i;
105
        }
106
107 5
        if (0 > $i) {
108 5
            return false;
109
        }
110
111 4
        ++$this->c[$i];
112
113 4
        while ($this->length - 1 > $i++) {
114 4
            $this->c[$i] = $this->c[$i - 1] + 1;
115
        }
116
117 4
        return true;
118
    }
119
}
120