Home > Back-end >  PHP Flatten tree array, mapping as a new array format s key => value
PHP Flatten tree array, mapping as a new array format s key => value

Time:04-10

I have a complex array in php like this :

[
    0 => [
        'id' => '2'
        'parent_id' => '1'
        'text' => 'Algoritma'
        'lvl' => '1'
        'nodes' => [
            0 => [
                'id' => '11'
                'parent_id' => '2'
                'text' => 'Flowchart'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=11'
            ]
            1 => [
                'id' => '12'
                'parent_id' => '2'
                'text' => 'Pseudo code'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=12'
            ]
        ]
        'href' => '/site/read-by-type?id=2'
    ]
    1 => [
        'id' => '3'
        'parent_id' => '1'
        'text' => 'Pemrograman'
        'lvl' => '1'
        'nodes' => [
            0 => [
                'id' => '4'
                'parent_id' => '3'
                'text' => 'Java'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=4'
            ]
            1 => [
                'id' => '5'
                'parent_id' => '3'
                'text' => 'PHP'
                'lvl' => '2'
                'nodes' => [
                    0 => [
                        'id' => '8'
                        'parent_id' => '5'
                        'text' => 'Yii2 Framework'
                        'lvl' => '3'
                        'href' => '/site/read-by-type?id=8'
                    ]
                    1 => [
                        'id' => '9'
                        'parent_id' => '5'
                        'text' => 'Laravel'
                        'lvl' => '3'
                        'href' => '/site/read-by-type?id=9'
                    ]
                ]
                'href' => '/site/read-by-type?id=5'
            ]
            2 => [
                'id' => '7'
                'parent_id' => '3'
                'text' => 'Javascript'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=7'
            ]
        ]
        'href' => '/site/read-by-type?id=3'
    ]
    2 => [
        'id' => '10'
        'parent_id' => '1'
        'text' => 'Sistem Operasi'
        'lvl' => '1'
        'nodes' => [
            0 => [
                'id' => '13'
                'parent_id' => '10'
                'text' => 'Mac OS'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=13'
            ]
            1 => [
                'id' => '14'
                'parent_id' => '10'
                'text' => 'Linux'
                'lvl' => '2'
                'href' => '/site/read-by-type?id=14'
            ]
        ]
        'href' => '/site/read-by-type?id=10'
    ]
]

I need flatten those array into key value format into ['id' => 'text']:

[
    2  => ' Algoritma'           // with 1 spaces based on those level
    11 => '  Flowchart',         // with 2 spaces based on those level
    12 => '  Pseudo code',       // with 2 spaces based on those level
    3  => ' Pemrograman'         // with 1 spaces based on those level
    4  => '  Java'               // with 2 spaces based on those level
    5  => '  PHP'                // with 2 spaces based on those level
    8  => '   Yii2 Framework'    // with 3 spaces based on those level
    9  => '   Laravel'           // with 3 spaces based on those level
    10 => ' Sistem Operasi'      // with 1 spaces based on those level

    ... so on
]

So far, I write a code like this:

public static function flattingTree(array $tree){
    $denormalizeTree = [];
    foreach ($tree as $node) {

        if(isset($node['nodes'])){
           // I am stuck  ...
        }

        $denormalizeTree[$node['id']] = $node['text'];
    }

    return $denormalizeTree;
}

And i just got only one level :

[
    2 => 'Algoritma'
    3 => 'Pemrograman'
    10 => 'Sistem Operasi'
]

Any help it so appreciated...

CodePudding user response:

A quick solution would be using a recursive function that iterates over the arrays and add the desired data to the final array.

The trick here is to have a function that accepts the unflattened array and a variable that will hold the data (where the data will be saved). The last parameter will be passed by reference so that the variable itself gets changed and thus the data is saved there.

function extract($arr, &$saveInto) {
    foreach ($arr as $el) {
        isset($el['id'], $el['text']) && ($saveInto[$el['id']] = $el['text']);
        isset($el['nodes']) && extract($el['nodes'], $saveInto); // recursive call
    }
}

Using the above function, you can flatten your array by calling it and specifying a variable that will hold the result.

$unflattenedArr = [ ... ]; // the array to be flattened
$finalArr = []; // the array that will hold the result
extract($unflattenedArr, $finalArr);
// at this stage $finalArr holds the result you need.

To make things even more simpler, you may encapsulate the extract function and you no longer need to prepare an empty array to hold the result.

function flatten($arr) {
    $r = []; // this function prepares an empty variable
    extract($arr, $r); // passes it to "extract" function
    return $r; // then returns it with the desired result
}

Now, you may flatten your array as follows:

$unflattenedArr = [ ... ]; // the array to be flattened
$finalArr = flatten($unflattenedArr); // call the new function that encapsulates "extract" function
// at this stage $finalArr holds the result you need.

Hope i have pushed you further.

CodePudding user response:

You are closer than you think. Just call your function recursively and add the result to your final array.

public function flattingTree(array $tree)
{
    $denormalizeTree = [];
    foreach ($tree as $node) {
        if (isset($node['nodes'])) {
            $denormalizeTree  = $this->flattingTree($node['nodes']);
        }
        $denormalizeTree[$node['id']] = $node['text'];
    }

    return $denormalizeTree;
}

Result:

$result = $this->flattingTree($array); 
print_r($result);

Array
(
    [11] => Flowchart
    [12] => Pseudo code
    [2] => Algoritma
    [4] => Java
    [8] => Yii2 Framework
    [9] => Laravel
    [5] => PHP
    [7] => Javascript
    [3] => Pemrograman
    [13] => Mac OS
    [14] => Linux
    [10] => Sistem Operasi
)
  • Related