优雅地将平面阵列爆炸成嵌套的关联数组?

时间:2013-09-11 21:30:34

标签: php arrays associative-array

我从API调用返回,它将类别树作为一个平面数组提供,其父/子关系用重复的字符串拼写出来。一小部分样本:

                [0] => Architecture & Street Scenes
                [1] => Architecture & Street Scenes/Architectural Detail
                [2] => Architecture & Street Scenes/Architectural Detail/Cast or Wrought Ironwork
                [3] => Architecture & Street Scenes/Architectural Detail/Cast or Wrought Ironwork/Balconies
                [4] => Architecture & Street Scenes/Architectural Detail/Cast or Wrought Ironwork/Fences
                [5] => Architecture & Street Scenes/Courtyards
                [6] => Architecture & Street Scenes/Exteriors & Street Scenes
                [7] => Architecture & Street Scenes/Interiors
                [8] => Architecture & Street Scenes/Street Lamps
                [9] => Art & Culture
                [10] => Art & Culture/Dance

是否有一种优雅的方式使用PHP从那里获取消除重复并通过子数组来表达关系?

                    [0] => Architecture & Street Scenes
                      [0] => Architectural Detail
                        [0] => Cast or Wrought Ironwork
                        [1] => Cast or Wrought Ironwork
                            [0] => Balconies
                            [1] => Fences
                      [1] => Courtyards
                      [2] => Exteriors & Street Scenes
                      [3] => Interiors
                      [4] => Street Lamps
                    [1] => Art & Culture
                        [0] => Dance

2 个答案:

答案 0 :(得分:1)

我的想法是你将每个标记用作创建哈希表的密钥。

<?php
$api = array(
    "Architecture & Street Scenes",
    "Architecture & Street Scenes/Architectural Detail",
    "Architecture & Street Scenes/Architectural Detail/Cast or Wrought Ironwork",
    "Architecture & Street Scenes/Architectural Detail/Cast or Wrought Ironwork/Balconies",
    "Architecture & Street Scenes/Architectural Detail/Cast or Wrought Ironwork/Fences",
    "Architecture & Street Scenes/Courtyards",
    "Architecture & Street Scenes/Exteriors & Street Scenes",
    "Architecture & Street Scenes/Interiors",
    "Architecture & Street Scenes/Street Lamps",
    "Art & Culture",
    "Art & Culture/Dance",
);

$end = array();

foreach ($api as $v) {
    $tokens = explode('/', $v);
    $parent = &$end;

    foreach ($tokens as $token) {
        if (!array_key_exists($token, $parent)) {
            $parent[$token] = array();
        }

        $parent = &$parent[$token];
    }
}

print_r($end);

输出:

Array
(
    [Architecture & Street Scenes] => Array
        (
            [Architectural Detail] => Array
                (
                    [Cast or Wrought Ironwork] => Array
                        (
                            [Balconies] => Array
                                (
                                )

                            [Fences] => Array
                                (
                                )

                        )

                )

            [Courtyards] => Array
                (
                )

            [Exteriors & Street Scenes] => Array
                (
                )

            [Interiors] => Array
                (
                )

            [Street Lamps] => Array
                (
                )

        )

    [Art & Culture] => Array
        (
            [Dance] => Array
                (
                )

        )

)

那么,当你迭代它们时,你可以这样做:

foreach ($end as $k => $v) {
    echo $k; //Here is your top level element.
    //You'd then iterate through it's children which are in $v.
}

答案 1 :(得分:1)

有几种方法可以做到这一点,这里是一个递归选项,无论输入数据的顺序如何,它都会实现同样的目的。

$output = array();

foreach($api_data as $line){
    process_children($line, $output);
}

function process_children($line, &$output){
    $split = explode('/', $line, 2);

    if(!isset($output[$split[0]]))
        $output[$split[0]] = array();

    if(isset($split[1]))
        process_children($split[1], $output[$split[0]]);
}

print_r($output);
相关问题