Passed
Pull Request — master (#8)
by Yo
01:38
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
/**
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