Home > Software engineering >  How I can flatten a tree in an orderly way?
How I can flatten a tree in an orderly way?

Time:06-07

I have PHP array (tree), something like this:

$categoryTree = [
    0 => [
        'id' => 1360,
        'parent' => 0,
        'name' => 'main A',
        'children' => [
            0 => [
                'id' => 1361,
                'parent' => 1360,
                'name' => 'sub a1'
            ],
            1 => [
                'id' => 57,
                'parent' => 1360,
                'name' => 'sub a2'
            ]
        ]
    ],
    1 => [
        'id' => 10,
        'parent' => 0,
        'name' => 'Main B'
    ]
];

I want to convert it into:

$categoryTree = [
    0 => [
        'id' => 1360,
        'parent' => 0,
        'name' => 'main A'
    ],
    1 => [
        'id' => 1361,
        'parent' => 1360,
        'name' => 'sub a1'
    ],
    2 => [
        'id' => 57,
        'parent' => 1360,
        'name' => 'sub a2'
    ],
    3 => [
        'id' => 10,
        'parent' => 0,
        'name' => 'Main B'
    ]
];

CodePudding user response:

It is rather simple. You walk recursively and only make a recursive call if the node has the key children. During the iteration in the foreach loop, keep collecting results in an result array.

<?php

function flatten($tree, &$results){
    foreach($tree as $kid){
        $kid_copy = $kid;
        unset($kid_copy['children']);
        $results[] = $kid_copy;
        if(isset($kid['children'])) flatten($kid['children'], $results);
    }
}

Online Demo

CodePudding user response:

Alternatively, using a generator, which then doesn't need the second argument:

function recurIter($arr) {
    foreach ($arr as $item) {
        $orig = $item;
        unset($item["children"]);
        yield $item;
        if (isset($orig["children"])) yield from recurIter($orig["children"]);
    }
}

$result = iterator_to_array(recurIter($categoryTree), false);
  • Related