展平树形数组并映射为新的数组格式s key => value的PHP方法
P粉563831052
P粉563831052 2023-09-03 20:28:52
[PHP讨论组]

我有一个在php中的复杂数组,像这样:

[
    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'
    ]
]

我需要将这些数组展平为键值对的格式,即 ['id' => 'text']:

[
    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个空格

    ... 以此类推
]

到目前为止,我写了这样的代码:

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

        if(isset($node['nodes'])){
           // 我被卡住了...
        }

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

    return $denormalizeTree;
}

但我只得到了一层:

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

非常感谢任何帮助...

P粉563831052
P粉563831052

全部回复(2)
P粉043470158

你比你想象的更接近。只需递归调用你的函数,并将结果添加到最终数组中。

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 = $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
)
P粉807397973

一个快速的解决方案是使用递归函数遍历数组并将所需数据添加到最终数组中。

关键在于有一个函数接受“未展开”的数组和一个变量来保存数据(数据将保存在该变量中)。最后一个参数将通过引用传递,以便变量本身被改变,从而将数据保存在其中。

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

使用上述函数,可以通过调用它并指定一个变量来展开数组以保存结果。

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

为了使事情更简单,可以封装 extract 函数,不再需要准备一个空数组来保存结果。

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

现在,可以按以下方式展开数组:

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

希望我已经帮助你进一步了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号