php - 如何将数组中含有从属关系的元素重新排列
怪我咯
怪我咯 2017-04-10 15:53:16
0
4
487

从数据表里取得一组二维数组,每个元素有键为 id 和 pid 的值,在不使用递归的情况下,如何按照其 pid 的值将元素移入到相应 id 元素中成为其子元素?

array(6) { [0] => array(3) { ["id"] => "21" ["pid"] => "0" ["name"] => "aaa" } [1] => array(3) { ["id"] => "22" ["pid"] => "0" ["name"] => "bbb" } [2] => array(3) { ["id"] => "23" ["pid"] => "0" ["name"] => "ccc" } [3] => array(3) { ["id"] => "24" ["pid"] => "23" ["name"] => "ddd" } [4] => array(3) { ["id"] => "25" ["pid"] => "23" ["name"] => "eee" } [5] => array(3) { ["id"] => "26" ["pid"] => "22" ["name"] => "fff" } }

重新排列为

array(3) { [0] => array(3) { ["id"] => "21" ["pid"] => "0" ["name"] => "aaa" } [1] => array(4) { ["id"] => "22" ["pid"] => "0" ["name"] => "bbb" ["child"]=> array(1) { [0] => array(3) { ["id"] => "26" ["pid"] => "22" ["name"] => "fff" } } } [2] => array(4) { ["id"] => "23" ["pid"] => "0" ["name"] => "ccc" ["child"]=> array(2) { [0] => array(3) { ["id"] => "24" ["pid"] => "23" ["name"] => "ddd" } [1] => array(3) { ["id"] => "25" ["pid"] => "23" ["name"] => "eee" } } } }

涉及层级关系只有两层。

怪我咯
怪我咯

走同样的路,发现不同的人生

reply all (4)
阿神

我想学算法的时候应该有讲过如何把递归改成循环实现。
一般递归都可以用队列+循环来实现,你先想想,空了来写程序。

你这个本来就是该循环实现的,哪里需要递归啊……

没得PHP的环境,用JS给你写个

要是看不懂 JS,C# 和 Java 看得懂不?PHP丢太久了,语法都忘了

javascriptvar data = [{ "id": "21", "pid": "0", "name": "aaa" }, { "id": "22", "pid": "0", "name": "bbb" }, { "id": "23", "pid": "0", "name": "ccc" }, { "id": "24", "pid": "23", "name": "ddd" }, { "id": "25", "pid": "23", "name": "eee" }, { "id": "26", "pid": "22", "name": "fff" }]; var map = {} var root = [] data.forEach(function(item) { map[item.id] = item; var parent = map[item.pid]; if (parent) { parent.child = parent.child || []; parent.child.push(item); } else { root.push(item); } }); console.log(JSON.stringify(root, null, 4));

输出

[ { "id": "21", "pid": "0", "name": "aaa" }, { "id": "22", "pid": "0", "name": "bbb", "child": [ { "id": "26", "pid": "22", "name": "fff" } ] }, { "id": "23", "pid": "0", "name": "ccc", "child": [ { "id": "24", "pid": "23", "name": "ddd" }, { "id": "25", "pid": "23", "name": "eee" } ] } ]
    洪涛

    非常感谢诸位的解答。看了你们的答案还在消化。基础不扎实还要多学习。
    自己参考了一下隔壁问题。实现的代码如下:

    $arr = array( array('id'=>21, 'pid'=>0, 'name'=>'aaa'), array('id'=>22, 'pid'=>0, 'name'=>'bbb'), array('id'=>23, 'pid'=>0, 'name'=>'ccc'), array('id'=>24, 'pid'=>23, 'name'=>'ddd'), array('id'=>25, 'pid'=>23, 'name'=>'eee'), array('id'=>26, 'pid'=>22, 'name'=>'fff'), ); $temp=[]; foreach ($arr as $item) { list($id,$pid,$name) = array_values($item); // 取出数组的值并分别生成变量 if(array_key_exists($pid, $temp)) // 检查临时数组$temp中是否存在键名与$pid的值相同的键 { $temp[$pid]['child'][]=array('id'=>$id,'pid'=>$pid,'name'=>$name); // 如果存在则新增数组至临时数组中键名为 $pid 的子元素 child 内 }else $temp[$id]=array('id'=>$id,'pid'=>$pid,'name'=>$name); // 如果不存在则新增数组至临时数组中并设定键名为 $id } $array = array_values($temp); // 将临时数组中以 $id 为键名的键修改为数字索引 echo "
    "; print_r($array);

    取值生成变量步骤有点多余,foreach 部分更新如下:

    foreach ($arr as $item) { if (array_key_exists($item['pid'], $temp)) { $temp[$item['pid']]['child'][]=$item; }else $temp[$item['id']]=$item; }
      小葫芦

      先算出每个数组的顶级pid,然后再排序下。

        大家讲道理
        $current['pid'],'child'=>array()); } }else{ if(array_key_exists($current['id'],$newArr)){ array_merge($newArr[$current['id']],$current); }else{ $newArr[$current['id']] = $current; } } $current = array_shift($arr); } // 更新数组和子数组的排序 ksort($newArr); foreach($newArr as $arr){ if(array_key_exists('child',$arr)){ usort($arr['child'],function($a,$b){ return $a['id'] > $b['id'] ? 1 : -1; }); } array_push($rtnArr,$arr); } // 打印 print_r($rtnArr); ?>
          Latest Downloads
          More>
          Web Effects
          Website Source Code
          Website Materials
          Front End Template
          About us Disclaimer Sitemap
          php.cn:Public welfare online PHP training,Help PHP learners grow quickly!