我有一个PHP对象的一维数组。每个对象都有两个属性,一个属性是对象的唯一ID,另一个属性是数组中另一个对象的唯一ID。例如:
array(3) {
[0]=>
object(stdClass)#1 (2) {
["ID"]=>
int(1)
["parentID"]=>
int(0)
}
[1]=>
object(stdClass)#2 (2) {
["ID"]=>
int(3)
["parentID"]=>
int(2)
}
[2]=>
object(stdClass)#3 (2) {
["ID"]=>
int(2)
["parentID"]=>
int(1)
}
}
我需要将这个一维数组转换为多维数组。我已经对此进行了一些尝试,但是如果没有针对每个嵌套级别的循环,我找不到完成它的方法。该算法需要能够适应假设无限级别的嵌套。我尝试过使用一些递归技术,但我从来没有这么做过。
为了增加一点复杂性,我得到的数组中的对象并不总是处于一种感性的顺序。我试图在上面的例子中复制这个;你会注意到ID为3的对象在ID为2的对象之前进入数组。因此它们可能也是一个排序算法。
理想情况下,上面的示例会显示如下:
Array
(
[0] => Array
(
[ID] => 1
[parentID] => 0
[0] => Array
(
[ID] => 2
[parentID] => 1
[0] => Array
(
[ID] => 3
[parentID] => 2
)
)
)
)
答案 0 :(得分:3)
试试这个算法:
// sort objects by parentID
function cmpNodes($a, $b) {
return $a->parentID - $b->parentID;
}
usort($objects, 'cmpNodes');
// define first node as root of tree
$tree = (array) array_shift($objects);
// lookup table for direct jumps
$idTable = array($tree['ID'] => &$tree);
foreach ($objects as $object) {
$node = (array) $object;
// test if parent node exists
if (!isset($idTable[$node['parentID']])) {
// Error: parent node does not exist
break;
}
// append new node to the parent node
$idTable[$node['parentID']][] = $node;
// set a reference in the lookup table to the new node
$idTable[$node['ID']] = &$idTable[$node['parentID']][count($idTable[$node['parentID']])-3];
}
// unset($idTable);
var_dump($tree);
我使用查找表($idtable
)将ID直接跳转到节点。
答案 1 :(得分:1)
所以,就像一个先驱 - 我根本不知道php,真的。我主要是一个c风格的语言开发人员(又名c,Objective c和Java)。因此,在php中可能更难做到这一点,但这是我要做的尝试:
//the original input array
oldArray;
//the output array
array[] newArray = new array[];
foreach (element : oldArray) {
//if the element is at the top, put it at the top of the array
if (element.parentId == 0) {
newArray.add(element);
} else {
//otherwise, find it's parent and put it in the child array of the parent
for (potentialParent : oldArray) {
if (potentialParent.id = element.parentId) {
potentialParent.array.add(element);
break;
}
}
}
}
一些注意事项:我假设你用指针传递一切。如果要复制对象,则更难,但并非不可能。我还假设您可以动态更改数组的大小。同样,我不太了解php - 如果你不能这样做,那么你需要一种程序方式来做这种行为。在Java中我会使用列表类型,或者只是复制数组并重新重置它。
这个算法工作的关键是孩子们被放置在他们的父母 - 无论他们身在何处 - 一次性通过。这意味着,无论顺序如何,都将在该单个过程中创建层次结构。如果你需要在你的例子中显示的父元素周围的包装器数组,你可以简单地在代码的末尾添加这样的东西:
finalArray = new array[];
finalArray[0] = newArray;
希望这有帮助。