Intereting Posts
Как проверить Google reCaptcha v2 с использованием форм фалкона / вольта? как установить задание cron из php-скрипта? Php form проверяется, когда значение флажка в массиве mysql-запроса? почему я получаю фатальную ошибку PHP, когда я хочу установить расширение Шаблоны проектирования для PHP – шаблон посетителя против шаблона servant Передача зашифрованного сервера данных на сервер, между 2 скриптами PHP Как включить и использовать HTTP PUT и DELETE с Apache2 и PHP? включить cors в .htaccess Разрешения с mkdir не будут работать Как я могу опубликовать статью на странице Фан-сайта Facebook, используя PHP и Open Graph API Поиск 4 наивысших значений из массива Как отправить сообщение Mandrill со специальными символами? Объективные причины использования пробелов вместо вкладок для отступов? Преобразование PDF в JPG-образ с помощью PHP Объект-объект «некоторая сущность» не может быть найден

Преобразование плоского массива в многомерное

У меня есть массив с данными дерева (по родительскому id). Я хочу преобразовать его в многомерный массив. Каков наилучший способ достичь этого? Есть ли для этого какая-то короткая функция?

Исходный массив:

$source = array( '0' => array( 'Menu' => array( 'id' => 45 'name' => 'Home' 'parent_id' => 1 ) ) '1' => array( 'Menu' => array( 'id' => 47 'name' => 'Get started' 'parent_id' => 1 ) ) '2' => array( 'Menu' => array( 'id' => 72 'name' => 'Attributes' 'parent_id' => 71 ) ) '3' => array( 'Menu' => array( 'id' => 73 'name' => 'Headings' 'parent_id' => 71 ) ) '4' => array( 'Menu' => array( 'id' => 75 'name' => 'Links' 'parent_id' => 71 ) ) '5' => array( 'Menu' => array( 'id' => 59 'name' => 'Images' 'parent_id' => 75 ) ) '6' => array( 'Menu' => array( 'id' => 65 'name' => 'Lists' 'parent_id' => 75 ) ) ); 

Некоторые родители отсутствуют в исходном массиве. Я хотел бы, чтобы элементы с отсутствующим родителем были root. Массив результатов:

 $result = array( '0' => array( 'Menu' => array( 'id' => 45 'name' => 'Home' 'parent_id' => 1 ) 'Children' => array() ) '1' => array( 'Menu' => array( 'id' => 47 'name' => 'Get started' 'parent_id' => 1 ) 'Children' => array() ) '2' => array( 'Menu' => array( 'id' => 72 'name' => 'Attributes' 'parent_id' => 71 ) 'Children' => array() ) '3' => array( 'Menu' => array( 'id' => 73 'name' => 'Headings' 'parent_id' => 71 ) 'Children' => array() ) '4' => array( 'Menu' => array( 'id' => 75 'name' => 'Links' 'parent_id' => 71 ) 'Children' => array( '0' => array( 'Menu' => array( 'id' => 59 'name' => 'Images' 'parent_id' => 75 ) 'Children' => array() ) '1' => array( 'Menu' => array( 'id' => 65 'name' => 'Lists' 'parent_id' => 75 ) 'Children' => array() ) ) ) ); 

Обновление: снятые квадратные скобки.

Я не думаю, что в PHP есть встроенная функция, которая делает это.

Я попробовал следующий код, и, похоже, он работает, чтобы подготовить вложенный массив так, как вы описываете:

 $nodes = array(); $tree = array(); foreach ($source as &$node) { $node["Children"] = array(); $id = $node["Menu"]["id"]; $parent_id = $node["Menu"]["parent_id"]; $nodes[$id] =& $node; if (array_key_exists($parent_id, $nodes)) { $nodes[$parent_id]["Children"][] =& $node; } else { $tree[] =& $node; } } var_dump($tree); 

Я написал аналогичный алгоритм в классе PHP, который я написал для своей презентации « Иерархические модели в SQL и PHP» , но я использовал объекты вместо простых массивов.

Я написал этот вариант, учитывая, что root parent_id равен 0 или отсутствует. Независимо от детей после родителей в БД (источник $) или нет.

 $source_by_id = array(); foreach ($source as &$row){ $source_by_id[$row['id']] = &$row; } foreach ($source_by_id as $id => &$row){ $source_by_id[ intval($row['parent_id']) ]['children'][$id] = &$row; } // remove cycling itself unset($source_by_id[0]['children'][0]); $result = $source_by_id[0]['children']; с $source_by_id = array(); foreach ($source as &$row){ $source_by_id[$row['id']] = &$row; } foreach ($source_by_id as $id => &$row){ $source_by_id[ intval($row['parent_id']) ]['children'][$id] = &$row; } // remove cycling itself unset($source_by_id[0]['children'][0]); $result = $source_by_id[0]['children']; 

Ключи массива результатов – соответствующие идентификаторы. Наслаждайтесь!

Я искал пример того, как это сделать, с категориями. В этом примере предполагается, что родители всегда будут иметь родительский идентификатор «0». В примере используется ZF2.

Нет ссылок или рекурсии. Фокус в выводе, вы ищете индекс [0], а для детей вы указываете parent_id как индекс.

 $categoryLookup = $this->getCategoryLookup($associateById=true); if ($assignedCategories) { $categoryHeirarchy = array(); foreach($assignedCategories as $assignedCategory) { $child = $categoryLookup[$assignedCategory->category_id]; $parent = $categoryLookup[$child->parent_id]; $categoryHeirarchy[$child->parent_id][] = $categoryLookup[$child->category_id]; $categoryHeirarchy[$parent->parent_id][$parent->category_id] = $categoryLookup[$parent->category_id]; } return $categoryHeirarchy; } <h3>Categories</h3> <dl class="dl-horizontal"> <?php foreach($this->categoryHeirarchy[0] as $parent): ?> <dt><?php echo $this->escapeHtml($parent->name); ?></dt> <?php foreach($this->categoryHeirarchy[$parent->category_id] as $child): ?> <dd><?php echo $this->escapeHtml($child->name); ?></dd> <?php endforeach; ?> <?php endforeach; ?> </dl>