Passed
Push — master ( f3dd8c...8b1d93 )
by Pol
11:27
created

Product   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
dl 0
loc 57
rs 10
c 1
b 0
f 0
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A on() 0 16 2
A __construct() 0 3 1
A cartesian() 0 13 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\Iterator\IterableIterator;
11
use function count;
12
13
/**
14
 * Class Product.
15
 */
16
final class Product implements Operation
17
{
18
    /**
19
     * @var iterable[]
20
     */
21
    private $iterables;
22
23
    /**
24
     * Product constructor.
25
     *
26
     * @param iterable ...$iterables
27
     */
28
    public function __construct(iterable ...$iterables)
29
    {
30
        $this->iterables = $iterables;
31
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function on(iterable $collection): Closure
37
    {
38
        $iterables = $this->iterables;
39
40
        $cartesian = function (iterable $input) {
41
            return $this->cartesian($input);
42
        };
43
44
        return static function () use ($iterables, $collection, $cartesian): Generator {
45
            $its = [$collection];
46
47
            foreach ($iterables as $iterable) {
48
                $its[] = new IterableIterator($iterable);
49
            }
50
51
            yield from $cartesian($its);
52
        };
53
    }
54
55
    /**
56
     * @param $iterable
57
     *
58
     * @return Generator|void
59
     */
60
    private function cartesian(iterable $iterable)
61
    {
62
        $u = array_pop($iterable);
0 ignored issues
show
Bug introduced by
$iterable of type iterable is incompatible with the type array expected by parameter $array of array_pop(). ( Ignorable by Annotation )

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

62
        $u = array_pop(/** @scrutinizer ignore-type */ $iterable);
Loading history...
63
64
        if (null === $u) {
65
            yield [];
66
67
            return;
68
        }
69
70
        foreach ($this->cartesian($iterable) as $p) {
71
            foreach ($u as $v) {
72
                yield $p + [count($p) => $v];
73
            }
74
        }
75
    }
76
}
77