如何将数组中含有从属关系的元素重新排列

WBOY
Release: 2016-06-06 20:30:25
Original
1037 people have browsed it

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

<code>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"
  }
}
</code>
Copy after login
Copy after login

重新排列为

<code>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"
            }
    }
  }
}
</code>
Copy after login
Copy after login

涉及层级关系只有两层。

回复内容:

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

<code>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"
  }
}
</code>
Copy after login
Copy after login

重新排列为

<code>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"
            }
    }
  }
}
</code>
Copy after login
Copy after login

涉及层级关系只有两层。

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

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

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

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

<code>javascript</code><code>var 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));
</code>
Copy after login

输出

<code>[
    {
        "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"
            }
        ]
    }
]
</code>
Copy after login

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

<code>$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 "<pre class="brush:php;toolbar:false">";
print_r($array);
Copy after login

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

<code>foreach ($arr as $item)
{
    if (array_key_exists($item['pid'], $temp))
    {       
        $temp[$item['pid']]['child'][]=$item;
    }else
        $temp[$item['id']]=$item;
}
</code>
Copy after login

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

<code><?php // 原本的数组, 偷个懒用JSON还原之
$arr = json_decode('[{
    "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"
}]',TRUE);

$newArr = $rtnArr = array();
$current = array_shift($arr);
while($current){
    if($current['pid']){
        if(array_key_exists($current['pid'],$newArr)){
            $newArr[$current['pid']]['child'][]= $current;
        }else{
            $newArr[$current['pid']] = array('id'=>$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);

?>
</code>
Copy after login
Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
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!