当您使用 hira ...heira... 树状数据时,将数据表示为树总是一个好主意。
以下片段可用于将您的平面数组转换为一棵树,您现在可以通过递归处理children
给定元素的所有数组来轻松处理它。
该方法执行以下操作:
- 遍历所有元素,直到平面数组为空(它假定每个元素都是根元素或在数组中具有匹配的父元素)
- 如果它是根元素,则将其添加到
result
根
- 如果匹配的父元素已经转移到
result
数组中,则将该元素添加为子元素。
我使用了第二个数组$refs
,它仅包含基于每个元素的 id 的引用,因为它允许在数组的任何级别插入元素,$result
而无需搜索正确的级别。
ps.:可能有更容易理解的递归方法。
pps.:我向任何元素添加了一个空的子数组,因此在插入子元素时我不必处理不存在的数组。
<?php
$arr = array(
array('id' => 1, 'parent' => 0, 'title' => 'XXX1', 'children'=>array()),
array('id' => 85, 'parent' => 0, 'title' => 'XXX2', 'children'=>array()),
array('id' => 41, 'parent' => 0, 'title' => 'XXX2', 'children'=>array()),
array('id' => 17, 'parent' => 0, 'title' => 'XXX3', 'children'=>array()),
array('id' => 66, 'parent' => 1, 'title' => 'XXX4', 'children'=>array()),
array('id' => 92, 'parent' => 1, 'title' => 'XXX5', 'children'=>array()),
array('id' => 65, 'parent' => 1, 'title' => 'XXX6', 'children'=>array()),
array('id' => 45, 'parent' => 41, 'title' => 'XXX7', 'children'=>array()),
array('id' => 19, 'parent' => 92, 'title' => 'XXX8', 'children'=>array()),
array('id' => 101, 'parent' => 45, 'title' => 'XXX9', 'children'=>array()),
array('id' => 102, 'parent' => 45, 'title' => 'XXX10', 'children'=>array()),
array('id' => 103, 'parent' => 19, 'title' => 'XXX11', 'children'=>array()),
array('id' => 104, 'parent' => 19, 'title' => 'XXX12', 'children'=>array()),
array('id' => 105, 'parent' => 19, 'title' => 'XXX13', 'children'=>array())
);
$newArr = unflattenArray($arr);
echo "<pre>";
print_r($newArr);
echo "</pre>";
function unflattenArray($flatArray){
$refs = array(); //for setting children without having to search the parents in the result tree.
$result = array();
//process all elements until nohting could be resolved.
//then add remaining elements to the root one by one.
while(count($flatArray) > 0){
for ($i=count($flatArray)-1; $i>=0; $i--){
if ($flatArray[$i]["parent"]==0){
//root element: set in result and ref!
$result[$flatArray[$i]["id"]] = $flatArray[$i];
$refs[$flatArray[$i]["id"]] = &$result[$flatArray[$i]["id"]];
unset($flatArray[$i]);
$flatArray = array_values($flatArray);
}
else if ($flatArray[$i]["parent"] != 0){
//no root element. Push to the referenced parent, and add to references as well.
if (array_key_exists($flatArray[$i]["parent"], $refs)){
//parent found
$o = $flatArray[$i];
$refs[$flatArray[$i]["id"]] = $o;
$refs[$flatArray[$i]["parent"]]["children"][] = &$refs[$flatArray[$i]["id"]];
unset($flatArray[$i]);
$flatArray = array_values($flatArray);
}
}
}
}
return $result;
}
这个方法会返回一个类似(outtake)的结果:
[1] => Array
(
[id] => 1
[parent] => 0
[title] => XXX1
[children] => Array
(
[0] => Array
(
[id] => 65
[parent] => 1
[title] => XXX6
[children] => Array
(
)
)
[1] => Array
(
[id] => 92
[parent] => 1
[title] => XXX5
[children] => Array
(
[0] => Array
(
[id] => 19
[parent] => 92
它仍然是未排序的,但现在是可以轻松处理的格式。
例如要对所有内容进行排序,您现在可以简单地使用递归排序方法,例如
sortMyArrays($newArr);
echo "<pre>";
print_r($newArr);
echo "</pre>";
function sortMyArrays(&$arr){
uasort($arr, "srt");
foreach ($arr as $a) {
sortMyArrays($a["children"]);
}
}
function srt($a, $b){
return $a["id"] - $b["id"];
}
当然,同样的逻辑也可以用来操作标题、显示数据等……