Elevator::walk()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 6
c 1
b 0
f 0
nc 5
nop 4
dl 0
loc 9
rs 9.6111
1
<?php
2
3
namespace PFlorek\Elevator;
4
5
class Elevator
6
{
7
    /**
8
     * Elevates an one-dimensional or any \Traversable to a multi-dimensional array.
9
     * Splits the keys by the delimiter into tokens. The tokens will become
10
     * the key of each node of the multi-dimensional array.
11
     *
12
     * @param array|\Traversable $flattened The map to be elevated to a tree.
13
     * @param string $delimiter The delimiter to split the map's keys.
14
     * @return array
15
     */
16
    public function up($flattened, $delimiter = '.')
17
    {
18
        if (!is_iterable($flattened)) {
19
            throw new \RuntimeException('Argument must be of type iterable (array or \Traversable).');
20
        }
21
22
        $result = [];
23
24
        foreach ($flattened as $path => $value) {
25
            $current = &$result;
26
27
            foreach (explode($delimiter, $path) as $key) {
28
                $current[$key] = !array_key_exists($key, $current) ? [] : (array)$current[$key];
29
30
                $current = &$current[$key];
31
            }
32
33
            $current = $value;
34
        }
35
36
        return $result;
37
    }
38
39
    /**
40
     * Flattens a multi-dimensional array or any \\Traversable into an one-dimensional array.
41
     *
42
     * @param array|\Traversable $elevated The tree to be fold down to a map.
43
     * @param string $delimiter The delimiter used to materialize the path.
44
     * @return array
45
     */
46
    public function down($elevated, $delimiter = '.')
47
    {
48
        if (!is_iterable($elevated)) {
49
            throw new \RuntimeException('Argument must be of type iterable (array or \Traversable).');
50
        }
51
52
        $result = [];
53
54
        $this->walk($result, $elevated, $delimiter);
0 ignored issues
show
Bug introduced by
It seems like $elevated can also be of type Traversable; however, parameter $elevated of PFlorek\Elevator\Elevator::walk() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

54
        $this->walk($result, /** @scrutinizer ignore-type */ $elevated, $delimiter);
Loading history...
55
56
        return $result;
57
    }
58
59
    /**
60
     * Internal pre-order tree walker appends each leaf with its materialized path to the resulting map.
61
     *
62
     * @param array $result
63
     * @param array $elevated
64
     * @param string $delimiter
65
     * @param string $path
66
     */
67
    private function walk(&$result, &$elevated, $delimiter, $path = null)
68
    {
69
        foreach ($elevated as $key => $value) {
70
            $current = null !== $path ? $path . $delimiter . $key : $key;
71
72
            if (!is_array($value) || !count($value)) {
73
                $result[$current] = $value;
74
            } else {
75
                $this->walk($result, $value, $delimiter, $current);
76
            }
77
        }
78
    }
79
}
80