Home  >  Q&A  >  body text

PHP method to flatten a tree array and map it to a new array format s key => value

<p>我有一个在php中的复杂数组,像这样:</p> <pre class="brush:php;toolbar:false;">[ 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' ] ]</pre> <p>我需要将这些数组展平为键值对的格式,即 ['id' => 'text']:</p> <pre class="brush:php;toolbar:false;">[ 2 => ' Algoritma' // 基于这些级别,有1个空格 11 => ' Flowchart', // 基于这些级别,有2个空格 12 => ' Pseudo code', // 基于这些级别,有2个空格 3 => ' Pemrograman' // 基于这些级别,有1个空格 4 => ' Java' // 基于这些级别,有2个空格 5 => ' PHP' // 基于这些级别,有2个空格 8 => ' Yii2 Framework' // 基于这些级别,有3个空格 9 => ' Laravel' // 基于这些级别,有3个空格 10 => ' Sistem Operasi' // 基于这些级别,有1个空格 ... 以此类推 ]</pre> <p>到目前为止,我写了这样的代码:</p> <pre class="brush:php;toolbar:false;">public static function flattingTree(array $tree){ $denormalizeTree = []; foreach ($tree as $node) { if(isset($node['nodes'])){ // 我被卡住了... } $denormalizeTree[$node['id']] = $node['text']; } return $denormalizeTree; }</pre> <p>但我只得到了一层:</p> <pre class="brush:php;toolbar:false;">[ 2 => 'Algoritma' 3 => 'Pemrograman' 10 => 'Sistem Operasi' ]</pre> <p>非常感谢任何帮助...</p>
P粉563831052P粉563831052384 days ago495

reply all(2)I'll reply

  • P粉043470158

    P粉0434701582023-09-04 14:57:41

    You are closer than you think. Just call your function recursively and add the results to the 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
    )

    reply
    0
  • P粉807397973

    P粉8073979732023-09-04 13:40:19

    A quick solution is to use a recursive function to iterate through the array and add the required data to the final array.

    The key is to have a function that accepts an "unexpanded" array and a variable to hold the data (the data will be held in the variable). The last argument will be passed by reference so that the variable itself is mutated to hold the data in it.

    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); // 递归调用
        }
    }

    Using the above function, you can expand the array by calling it and specifying a variable to save the result.

    $unflattenedArr = [ ... ]; // 要展开的数组
    $finalArr = []; // 将保存结果的数组
    extract($unflattenedArr, $finalArr);
    // 此时 $finalArr 中保存了所需的结果。

    To make things simpler, you can encapsulate the extract function, no longer needing to prepare an empty array to save the results.

    function flatten($arr) {
        $r = []; // 此函数准备一个空变量
        extract($arr, $r); // 将其传递给“extract”函数
        return $r; // 然后返回带有所需结果的变量
    }

    Now, the array can be expanded as follows:

    $unflattenedArr = [ ... ]; // 要展开的数组
    $finalArr = flatten($unflattenedArr); // 调用封装了“extract”函数的新函数
    // 此时 $finalArr 中保存了所需的结果。

    Hope I've helped you further.

    reply
    0
  • Cancelreply