Итак, просто как предшественник - я вообще не знаю php. Я в первую очередь разработчик языка c-style (aka 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;
Надеюсь, это поможет.