2013-02-19 92 views
1

假设我有此数组:转换一个维阵列成多维数组

Array 
(
    [0] => Array 
    (
    [name] => ELECTRONICS 
    [depth] => 0 
) 

    [1] => Array 
    (
    [name] => TELEVISIONS 
    [depth] => 1 
) 

    [2] => Array 
    (
    [name] => TUBE 
    [depth] => 2 
) 

    [3] => Array 
    (
    [name] => LCD 
    [depth] => 2 
) 

    [4] => Array 
    (
    [name] => PLASMA 
    [depth] => 2 
) 

    [5] => Array 
    (
    [name] => PORTABLE ELECTRONICS 
    [depth] => 1 
) 
) 

我希望它被转换成一个多维阵列,使得以比以前的元件更高的深度立即元件将使用关键字“children”进入前一个元素。像这样:

Array 
(
    [0] => Array 
    (
    [name] => ELECTRONICS 
    [depth] => 0 
    [children] => Array 
    (
     [0] => Array 
     (
     [name] => TELEVISIONS 
     [depth] => 1 
     [children] => Array 
     (
      [0] => Array 
      (
      [name] => TUBE 
      [depth] => 2 
     ) 

      [1] => Array 
      (
      [name] => LCD 
      [depth] => 2 
     ) 

      [2] => Array 
      (
      [name] => PLASMA 
      [depth] => 2 
     ) 
     ) 
    ) 

     [1] => Array 
     (
     [name] => PORTABLE ELECTRONICS 
     [depth] => 1 
    ) 
    ) 
) 
) 

非常感谢您的帮助。谢谢;)

+0

目前我在我束手无策尝试使用一对夫妇如果在一个for循环但遗憾的是无济于事的条件... – VeeBee 2013-02-19 15:58:39

+0

有这里的之间的代码没有逻辑连接来-了一些array_push方法父母和孩子。您在初始输入中唯一知道的是深度级别。人们可能会根据深度创建一棵树,但看起来像嵌套像条款一样。 TUBE,LCD和PLASMA是电视的孩子,但PORTABLE ELECTRONICS没有孩子。代码如何知道这种关系? – tmsimont 2013-02-19 15:59:57

+0

哎呀,对不起,我错过了这个:“我希望它被转换成一个多维数组,使深度高于前一个元素的直接元素将进入前一个元素的内部,使用键”children“” – tmsimont 2013-02-19 16:00:52

回答

1

这里是我的裂纹吧...使用foreach循环和指针数组保持了一堆轨道不同的父指针。

$multi_dimensional = array(); 
$last_depth = 0; 
$parent = &$multi_dimensional; 
$parents[$last_depth] = &$parent; 


foreach ($start as $idx => $data) { 
    // same/increasing depth 
    if ($last_depth <= $data['depth']) { 
    $parent['children'][] = $data; 
    } 

    // increasing depth 
    if ($last_depth < $data['depth']) { 
    $parents[$last_depth] = &$parent; 
    } 

    // decreasing depth 
    if ($last_depth > $data['depth']) { 
    $parent = &$parents[$data['depth']-1]; 
    $parent['children'][] = $data; 
    } 

    // look ahead and prepare parent in increasing 
    if (isset($start[$idx+1]) && $start[$idx+1]['depth'] > $data['depth']) { 
    $last_insert_idx = count($parent['children'])-1; 
    $parent = &$parent['children'][$last_insert_idx]; 
    } 
    $last_depth = $data['depth']; 
} 

// initial values are in child "children" array 
$result = $multi_dimensional['children']; 
+0

cernunnos的递归解决方案也可以工作,但由于它是非递归的,所以这个方法更高效。感谢你的付出! – VeeBee 2013-02-19 23:58:43

+0

没问题!我喜欢这样的逻辑谜题 – tmsimont 2013-02-20 00:10:51

1

我道歉的名称和它的递归性质。另外,请注意,这个功能将“消灭”,如果你想保持它

function multiDimensionate(&$arr, $currentLevel = 0) { 
    $root = array(); 

    foreach ($arr as &$elem){ 
    if ($elem["depth"] == $currentLevel) { 
     $root[] = $elem; 
     unset($elem); 
    } else if ($elem["depth"] == $currentLevel + 1) { 
     $root[count($root)-1]["children"] = multiDimensionate($arr,$elem["depth"]);  
    } 
    } 

    return $root; 
} 

编辑您的原始数组所以使用克隆:正如评析指出,先前的功能wasnt正常工作,这应该没问题,仍然有破坏原始数组的副作用。

+0

看起来像PORTABLE ELECTRONICS没有得到提升备份到顶层 – tmsimont 2013-02-19 16:34:15

2

这是一个棘手的问题。我不知道这是否是实现这一目标的最优化的方式,但它的工作原理:

function flat_to_tree($array, $depth = 0) 
{ 
    $out = array(); 
    $inCurrentDepth = true; 

    foreach ($array as $key => $value) { 
    if ($value['depth'] < $depth) { 
     return $out; 
    } 

    if ($value['depth'] === $depth) { 
     $inCurrentDepth = true; 
     $out[] = $value; 
    } 

    if ($inCurrentDepth && $value['depth'] > $depth) { 
     $inCurrentDepth = false; 
     $out[$key - 1]['children'] = flat_to_tree(array_slice($array, $key), $value['depth']); 
    } 
    } 

    return $out; 
} 
+0

很好地使用递归和php本地功能。我去了不太令人兴奋的foreach循环方法 – tmsimont 2013-02-19 17:08:43

+0

我试过这个,但它没有输出所需的结果。 – VeeBee 2013-02-19 23:54:40