Доброго времени суток и с Новым Годом. Помогите решить задачу, голову сломал, рекурсия тоже сломалась. P.S. Это для древовидных категорий в админке OpenCart. И это не велосипед, я знаю как работает такое же меню в ocStore. Получаю однородный массив категорий: 'categories' => array 0 => array 'category_id' => string '28' 'parent_id' => string '25' 'name' => string 'Monitors' 1 => array 'category_id' => string '28' 'parent_id' => string '25' 'name' => string 'Monitors' У каждой категории есть parent_id и category_id, по которым мы можем их идентифицировать и прицепить к друг-другу в новом массиве. Главной (первого уровня) parent_id является 0. Необходимо создать из массива новый массив с деревом категорий. Если подумать, это легко для двухуровневого меню, а если меню многоуровневое? Я смотрел в сторону рекурсии, но не получилось. Прошу помощи у вас, объясните только логику работы, код напишу сам. Заранее спасибо. --- Добавлено, 1 янв 2014 --- На других языках программирования я бы справился лишь одним проходом по массиву, но тут не могу понять работу с указателями. --- Добавлено, 1 янв 2014 --- Решил задачу, для решения необходимо всего один раз пройтись по массиву и добавлять к каждой категории ссылку на дочерний элемент этого же массива. И никакой рекурсии. А для того, чтобы добавить все категории, у которых parent_id = 0 т.е. они содержатся в главной категории, необходимо было создать эту самую категорию, где category_id = 0 =) PHP: $cate[0] = array('name'=>'root','category_id'=>0); foreach ($cate as $key => $value) { if (isset($value['parent_id'])) { $cate[$value['parent_id']]['childs'][] = &$cate[$key]; } } --- Добавлено, 1 янв 2014 --- Получился вот такой массив Код: array (size=2) 0 => array (size=4) 'store_id' => int 0 'name' => string 'Your Store <b>(Default)</b>' (length=27) 'url' => string 'http://1551.opencart.im/' (length=24) 'categories' => array (size=3) 'name' => string 'root' (length=4) 'category_id' => int 0 'childs' => array (size=8) 0 => array (size=4) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Cameras' (length=7) 1 => array (size=4) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Software' (length=8) 2 => array (size=5) 'parent_id' => string '0' (length=1) 'pattern_id' => string '1' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Components' (length=10) 'childs' => array (size=5) 0 => array (size=5) 'parent_id' => string '25' (length=2) 'pattern_id' => string '1' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Monitors' (length=8) 'childs' => array (size=2) 0 => array (size=4) 'parent_id' => string '28' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 1' (length=6) 1 => array (size=4) 'parent_id' => string '28' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 2' (length=6) 1 => array (size=4) 'parent_id' => string '25' (length=2) 'pattern_id' => string '1' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Web Cameras' (length=11) 2 => array (size=4) 'parent_id' => string '25' (length=2) 'pattern_id' => string '1' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Scanners' (length=8) 3 => array (size=4) 'parent_id' => string '25' (length=2) 'pattern_id' => string '1' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Printers' (length=8) 4 => array (size=4) 'parent_id' => string '25' (length=2) 'pattern_id' => string '1' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Mice and Trackballs' (length=19) 3 => array (size=4) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Phones & PDAs' (length=17) 4 => array (size=5) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Desktops' (length=8) 'childs' => array (size=2) 0 => array (size=4) 'parent_id' => string '20' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Mac' (length=3) 1 => array (size=4) 'parent_id' => string '20' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'PC' (length=2) 5 => array (size=5) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'MP3 Players' (length=11) 'childs' => array (size=18) 0 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 5' (length=6) 1 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 4' (length=6) 2 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 6' (length=6) 3 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 7' (length=6) 4 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 8' (length=6) 5 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 9' (length=6) 6 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 11' (length=7) 7 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 12' (length=7) 8 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 15' (length=7) 9 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 16' (length=7) 10 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 17' (length=7) 11 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 18' (length=7) 12 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 19' (length=7) 13 => array (size=5) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 20' (length=7) 'childs' => array (size=1) 0 => array (size=4) 'parent_id' => string '52' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 25' (length=7) 14 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 21' (length=7) 15 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 22' (length=7) 16 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 23' (length=7) 17 => array (size=4) 'parent_id' => string '34' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'test 24' (length=7) 6 => array (size=5) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Laptops & Notebooks' (length=23) 'childs' => array (size=2) 0 => array (size=4) 'parent_id' => string '18' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Windows' (length=7) 1 => array (size=4) 'parent_id' => string '18' (length=2) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Macs' (length=4) 7 => array (size=4) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Tablets' (length=7) 1 => array (size=4) 'store_id' => int 1 'name' => string 'Store 2' (length=7) 'url' => string 'http://cdn1.opencart.im/' (length=24) 'categories' => & array (size=3) 'name' => string 'root' (length=4) 'category_id' => int 0 'childs' => array (size=2) 0 => & array (size=4) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Cameras' (length=7) 1 => & array (size=4) 'parent_id' => string '0' (length=1) 'pattern_id' => string '0' (length=1) 'use_for_child' => string '0' (length=1) 'name' => string 'Desktops' (length=8) --- Добавлено, 1 янв 2014 --- Всем спасибо, сам задал - сам ответил =)
Была у меня когда-то подобная задача, только я создавал дерево комментариев к товару (делал вместо стандартных комментариев нормальную систему для обсуждения товара). Я при сохранении дочерного элемента, добавлял к родителю указатель на наличие дочерных элементов (и, конечно, дочерному элементу вписывал id родителя). А при построении дерева проходил циклом по первому уровню комментариев (у которых нет родителей) и при наличии указателя на дочерные элементы, рекурсивно прочёсывал комментарии в их поиске. Рекурсиво потому, что при наличии у дочерного комментария указателя на дочерные элементы, заново вызывал функцию поиска потомков. В результате я получал многоуровневый массив, который полностью соответствовал дереву.