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

NAryTreeFactory   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 44
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 6
eloc 17
c 1
b 0
f 0
dl 0
loc 44
ccs 16
cts 16
cp 1
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A fromLevelOrderList() 0 29 6
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