Вычислить глубину элемента в PHP из плоского массива только с идентификатором родительского элемента

У меня есть плоский массив:

Array
(
[] => Array
(
[id] => 346788
[parent_id] => 0
[item_title] => 'title Here'
[item_description] => 'some text'
)

[] => Array
(
[id] => 12346
[parent_id] => 0
[item_title] => 'title Here'
[item_description] => 'some text'
)

[] => Array
(
[id] => 56745
[parent_id] => 12346
[item_title] => 'title Here'
[item_description] => 'some text'
)

[] => Array
(
[id] => 3564
[parent_id] => 12346
[item_title] => 'title Here'
[item_description] => 'some text'
)

[] => Array
(
[id] => 2345234
[parent_id] => 56745
[item_title] => 'title Here'
[item_description] => 'some text'
)

[] => Array
(
[id] => 433546
[parent_id] => 56745
[item_title] => 'title Here'
[item_description] => 'some text'
)
)

который имеет идентификатор каждого элемента в виде пары ключ / значение, а также идентификатор родительского элемента. Первое, что должно произойти, — это то, что плоский массив должен быть превращен в иерархический массив, одновременно сохраняя всю остальную информацию, которая есть у каждого из элементов массива. хитрость в том, что мне нужно знать глубину этого элемента в массиве как уровень на основе 0. таким образом, родитель будет равен 0, первый ребенок будет равен 1, и т. д. и т. д., и он будет сохранен в конечном массиве:

function build_tree(array &$elements, $parentId = 0, $depth = 0) {

$branch = array();

foreach ($elements as &$element) {

if ($element['parent_id'] == $parentId) {
$children = build_tree( $elements, $element['id'], $depth + 1 );
if ($children) {
$element['children'] = $children;
}
$branch[$element['id']] = $element;
$branch[$element['id']]['depth'] = $depth;
unset($element);
}
}
return $branch;
}

Во-вторых, мне также нужна дополнительная функция, которая может вычислять глубину из исходного плоского массива:

function calculate_depth( $item_id, array $array ) {

return $item_depth;
}

0

Решение

Если у вас нет доступа к дереву, то в любом случае вам потребуется полное сканирование массива, поэтому я бы использовал hashmap:

$map = array();
foreach ($elements as $e)
$map[$e['itemID']] = array(
'parent' => $e['parentID'],
'depth' => null
);

Итак, чтобы получить глубину, вы должны отсканировать эту родительскую карту сейчас, что займет время, пропорциональное глубине:

function depth(&$map, $id) {
$depth = 0;
$the_id = $id;
while ($map[$id]['parent']) {
if ($map[$id]['depth'] !== null) {
$depth += $map[$id]['depth'];
break;
}
$id = $map[$id]['parent'];
$depth++;
}
$map[$the_id]['depth'] = $depth;
return $depth;
}

В приведенном выше коде добавлен небольшой механизм кэширования, так что вычисление всех глубин будет по-прежнему занимать линейное время.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]