Passed
Pull Request — master (#8)
by Yo
01:38
created

NAryTreeFactory   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 40
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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

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
/**
10
 * @template TNode of Node The actual Node class
11
 * @template TValue of mixed The actual Node value type
12
 *
13
 * @phpstan-type TNodeCreator callable(TValue $v): TNode
14
 *
15
 */
16
class NAryTreeFactory
17
{
18
    /**
19
     * @TODO write example regarding expecting list format !
20
     *
21
     * @param mixed[] $list
22
     * @phpstan-param list<TValue|null> $list
23
     * @phpstan-param TNodeCreator $nodeCreator
24
     *
25
     * @phpstan-return ?TNode
26
     */
27 4
    public static function fromLevelOrderList(array $list, callable $nodeCreator): ?Node
28
    {
29 4
        $tailIdx = count($list) - 1;
30 4
        if ($tailIdx < 0 || (0 === $tailIdx && null === $list[0])) {
31 2
            return null;
32
        }
33
34
        /** @var \SplQueue<Node> $queue */
35 2
        $queue = new \SplQueue();
36
37 2
        $root = call_user_func($nodeCreator, $list[0]); // @phpstan-ignore argument.type
38 2
        $queue->enqueue($root);
39
40 2
        $idx = 2; // Should be index 1, but it contains the null value indicating end of children for "root" level !
41 2
        while ($idx <= $tailIdx) {
42 2
            $parentNode = $queue->bottom(); // =peek() => next value to dequeue from a SplQueue!
43
44
            // Append children to the current parent node until a null value is found
45 2
            if (null !== $list[$idx]) {
46 2
                $parentNode->children[] = $node = call_user_func($nodeCreator, $list[$idx]);
47 2
                $queue->enqueue($node);
48
            } else {
49
                // Drop current parent node as there is no more children to attach
50 2
                $queue->dequeue();
51
            }
52 2
            ++$idx;
53
        }
54
55 2
        return $root;
56
    }
57
}
58