按行中的值嵌套数组

时间:2016-03-25 21:32:33

标签: php arrays nested

假设我有一个像波纹管一样的数组。数组中的第二个值是级别/深度。

$arr = array(
    ['product 1', 0],
    ['product 2', 1],
    ['product 3', 1],
    ['product 4', 2],
    ['product 5', 0]
);

以视觉方式表示:

product 1
   product 2
   product 3
      product 4
product 5

我正在尝试将其转换为:

Array
(
    [0] => Array
        (
            [0] => product 1
            [1] => 0
            [children] => Array
                (
                    [0] => Array
                        (
                            [0] => product 2
                            [1] => 1
                        )

                    [1] => Array
                        (
                            [0] => product 3
                            [1] => 1
                            [children] => Array
                                (
                                    [0] => product 4
                                    [1] => 2
                                )
                        )
                )
        )
    [1] => Array
        (
            [0] => product 5
            [1] => 0
        )

)

无限级别。

我几乎整天都用头撞在墙上,我甚至没有接近解决方案。令人沮丧的是,不能自己解决问题,我不得不承认失败。我没有有用的代码可供展示。我知道这基本上是要求代码,但这超出了我的脑力。 如果有人接受一点挑战,那可能就是:)。我会非常感激。

谢谢。

2 个答案:

答案 0 :(得分:1)

我已经将初始数组扩展了一个级别以满足您的要求 - "无限级别。"
这里是带有递归函数的解决方案,我称之为CREDITED ACC

findParent

输出:

$arr = array(
    ['product 1', 0],
    ['product 2', 1],
    ['product 3', 1],
    ['product 4', 2],
    ['product 5', 3],
    ['product 6', 3],
    ['product 7', 0],
    ['product 8', 1],
);

$structure = [];
foreach ($arr as $k => $v) {
    if (empty($structure) || $v[1] == 0) {
        $structure[] = $v;
    } else {
        $last = array_pop($structure);
        $current_key = $k;
        $parent_key = "";

        while (--$current_key) {
            if ($v[1] > $arr[$current_key][1]) {
                $parent_key = $arr[$current_key][0];
                break;
            }
        }

        if ($v[1] == 1) {
            (isset($last['children']))? $last['children'][] = $v : $last['children'] = [$v];
        } else {
            findParent($last['children'], $parent_key, $v);
        }
        array_push($structure, $last);
    }
}

function findParent(&$el = [], $parent_key = "", $child = []){
    foreach ($el as &$v) {
       if ($v[0] == $parent_key) {
           (isset($v['children']))? $v['children'][] = $child : $v['children'] = [$child];
           break;
       } elseif (isset($v['children'])) {
           findParent($v['children'], $parent_key, $child);
       }
    }    
}

print_r($structure);

答案 1 :(得分:0)

我认为更好的输入结构将是(如果你有一个id):

$arr = array(
  ['id' => 1, 'name' => 'product 1', 'cid' => 0, 'level' => 0],
  ['id' => 2, 'name' => 'product 2', 'cid' => 1, 'level' => 1],
  ['id' => 3, 'name' => 'product 3', 'cid' => 2, 'level' => 2],
  ['id' => 4, 'name' => 'product 4', 'cid' => 3, 'level' => 3],
  ['id' => 5, 'name' => 'product 5', 'cid' => 0, 'level' => 0]
);

其中cid - 父项的内容

$tree = [];
foreach($arr as $item){
    $tree[ $item['level'] ][ $item['cid'] ][] = $item;
} unset($item);

输出树的递归函数

function echoTree($tree, $level = 0, $parent = 0, $prefix = ''){
    $level = intval($level);
    $parent= intval($parent);

    if(isset($tree[ $level ][ $parent ])){
        foreach($tree[ $level ][ $parent ] as $item){
            echo "{$prefix}{$item['name']}";
            echoTree($tree, $level + 1, $item['id'], $prefix.'---');
        }
    }
}

尝试一下,但我没有测试它