Массивы PHP - Как к 1-мерному массиву во вложенный многомерный массив?

При получении иерархической структуры от MySQL (таблица с одним столбцом ID и одним столбцом PARENT, показывающим иерархические отношения), я отображаю результат в перечислимый массив следующим образом (для этого примера, числа произвольны):

Array ( [3] => Array ( [7] => Array () ), [7] => Array ( [8] => Array () ) )

Уведомление 3 является родителем 7, и 7 родитель 8 (это могло продолжиться и на; и любой родитель мог иметь несколько детей).

Я хотел уменьшить этот массив во вложенный многомерный массив следующим образом:

Array ( [3] => Array ( [7] => Array ( [8] => Array () ) ) )

Таким образом, каждому НОВОМУ идентификатору автоматически присваивают пустой массив. Независимо, дети любого идентификатора будут продвинуты в массив их родителя.

Смотрите на следующую иллюстрацию для дальнейшего разъяснения:

сопроводительный текст http://img263.imageshack.us/img263/4986/array.gif

Это, вероятно, приведет к сложной рекурсивной операции, так как я всегда должен проверять, существует ли родитель с каким-либо определенным идентификатором уже (и если так, продвиньте значение в его массив).

Существует ли встроенная функция php, которая может помочь мне с этим? У Вас есть какая-либо идея относительно того, как пойти о построении этого? Если это имеет значение я использую это для созданного панель навигации в Wordpress (который может содержать категории, подкатегории, сообщения... по существу что-либо).

6
задан Gal 23 May 2010 в 17:19
поделиться

2 ответа

Идея состоит в том, что вы сохраняете вспомогательный массив со всеми найденными узлами (родительскими и дочерними). Значения этих массивов являются ссылками, которые подтверждают ваш результат.

Это строит дерево за линейное время (array_key_exists выполняет поиск в хеш-таблице, которая в среднем составляет O (1)):

//table contains (id, parent)
$orig = array(
    11 => 8,
    7 => 3,
    8 => 7,
    99 => 8,
    16 => 8,
);

$childrenTable = array();
$result = array();

foreach ($orig as $n => $p) {
    //parent was not seen before, put on root
    if (!array_key_exists($p, $childrenTable)) {
        $childrenTable[$p] = array();
        $result[$p] = &$childrenTable[$p];
    }
    //child was not seen before
    if (!array_key_exists($n, $childrenTable)) {
        $childrenTable[$n] = array();
    }

    //root node has a parent after all, relocate
    if (array_key_exists($n, $result)) {
        unset($result[$n]);
    }

    $childrenTable[$p][$n] = &$childrenTable[$n];
}
unset($childrenTable);

var_dump($result);

дает

array(1) {
  [3]=>
  array(1) {
    [7]=>
    array(1) {
      [8]=>
      array(3) {
        [11]=>
        array(0) {
        }
        [99]=>
        array(0) {
        }
        [16]=>
        array(0) {
        }
      }
    }
  }
}

EDIT: unset $ childrenTable в конце для снять флажки ссылок. На практике вы, вероятно, все равно захотите выполнить операцию внутри функции.

1
ответ дан 17 December 2019 в 20:29
поделиться

Этот вопрос и ответы на него должны быть вам полезны: превратить результат базы данных в массив.

Обязательно прочитайте PDF-презентацию @Bill Karwin, в частности, темы, касающиеся таблицы Closure.

1
ответ дан 17 December 2019 в 20:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: