Passed
Push — master ( 1d23cf...097598 )
by Yo
01:45
created

NAryTreeFactory::fromLevelOrderList()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 16
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 29
ccs 16
cts 16
cp 1
crap 6
rs 9.1111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yoanm\CommonDSA\Factory;
6
7
use Yoanm\CommonDSA\DataStructure\NAryTree\Node;
8
9
class NAryTreeFactory
10
{
11
    /**
12
     * @TODO write example regarding expecting list format !
13
     *
14
     * @template TNode of Node The actual Node class
15
     * @template TValue of mixed The actual Node value type
16
     *
17
     *
18
     * @param mixed[] $list ⚠ Must be a 0 indexed list, 0 to n consecutive indexes
19
     * @phpstan-param  list<TValue|null> $list
20
     * @phpstan-param callable(TValue $v): TNode $nodeCreator
21
     *
22
     * @phpstan-return ?TNode
23
     */
24 4
    public static function fromLevelOrderList(array $list, callable $nodeCreator): ?Node
25
    {
26 4
        $tailIdx = count($list) - 1;
27 4
        if ($tailIdx < 0 || (0 === $tailIdx && null === $list[0])) {
28 2
            return null;
29
        }
30
31
        /** @var \SplQueue<Node> $queue */
32 2
        $queue = new \SplQueue();
33
34 2
        $root = call_user_func($nodeCreator, $list[0]); // @phpstan-ignore argument.type
35 2
        $queue->enqueue($root);
36
37 2
        $idx = 2; // Should be index 1, but it contains the null value indicating end of children for "root" level !
38 2
        while ($idx <= $tailIdx) {
39 2
            $parentNode = $queue->bottom(); // =peek() => next value to dequeue from a SplQueue!
40
41
            // Append children to the current parent node until a null value is found
42 2
            if (null !== $list[$idx]) {
43 2
                $parentNode->children[] = $node = call_user_func($nodeCreator, $list[$idx]);
44 2
                $queue->enqueue($node);
45
            } else {
46
                // Drop current parent node as there is no more children to attach
47 2
                $queue->dequeue();
48
            }
49 2
            ++$idx;
50
        }
51
52 2
        return $root;
53
    }
54
}
55