Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Полный путь категорий и подкатегорий из "дерева" или двумерного массива
Покинул форум
Сообщений всего: 111
Дата рег-ции: Окт. 2009 Откуда: Казахстан, Алматы
Помог: 0 раз(а)
Ребята, требуется нехитрая помощь, кто может, подскажите, пожалуйста, как реализовать: я получил из массива "дерево", теперь мне нужно вытащить из него пути к категориям и подкатегориям. Я достаточно хорошо знаю php, но совсем не дружу с логикой и математикой Мне нужно вместо:
Ссылка в дереве ([link]) и в двумерном массиве выглядит одинаково, вот так:
<ul><li><a href="">text</a></li></ul>
Ссылки я вытащу сам на каты, мне нужно просто пример, как вытащить айди категории, вместо которых я потом прегами заменю "href" (название категории на англ.) в ссылках на полный путь. Надеюсь, объяснил исчерпывающе
Если не готовый пример, то хотя бы логику обработки нужно, был бы очень благодарен.
isle
Отправлено: 12 Июня, 2010 - 02:03:58
Гость
Покинул форум
Сообщений всего: 111
Дата рег-ции: Окт. 2009 Откуда: Казахстан, Алматы
Помог: 0 раз(а)
Блин, капец, 2 дня убил (хотя дерево строил... м... даже сказать стыдно сколько дней ) и только что осенило, решил поделиться, так как в сети никаких примеров не нашел, может, кому пригодится:
Решение корявое и ограниченное по вложенности, сейчас вложенность - 3, можно сделать любую просто добавив еще циклов.
Кто хорошо шпарит в деревьях, многомерных массивах и циклах, поделитесь, пожалуйста, более рациональным примером, очень нужно. Спасибо за внимание.
Joo
Отправлено: 12 Июня, 2010 - 07:04:55
Гость
Покинул форум
Сообщений всего: 99
Дата рег-ции: Нояб. 2009 Откуда: Казахстан
Помог: 1 раз(а)
Это очень просто реализуется на классах, у вас сразу отпадет ограничение по уровню вложенности и обход дерева примет элементарный вид.
----- "Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог
isle
Отправлено: 12 Июня, 2010 - 07:13:13
Гость
Покинул форум
Сообщений всего: 111
Дата рег-ции: Окт. 2009 Откуда: Казахстан, Алматы
Помог: 0 раз(а)
Joo пишет:
Это очень просто реализуется на классах, у вас сразу отпадет ограничение по уровню вложенности и обход дерева примет элементарный вид.
Зачем мне классы для построения дерева, если я всё написал в несколько строчек и получил чистое дерево с нужными мне элементами? (просто форматирование потерялось здесь и ненаглядно выводится массив)
Другое дело - не знаю как написать простую функцию для одновременной распечатки самого дерева и выборки путей категорий/подкатегорий... Пришлось клепать мега-функцию, вернее даже две: распечатка самого дерева и выборка (жестко завязанная по вложенности) путей категорий/подкатегорий, простенький примерчик для наглядности который привел выше.
Если знаете как можно всё объединить в кучу для минимизации (оптимизации?) кода и без искусственных ограничений вложенности, был бы очень благодарен, а то уже мозг просто кипит, скоро взорвусь
Покинул форум
Сообщений всего: 99
Дата рег-ции: Нояб. 2009 Откуда: Казахстан
Помог: 1 раз(а)
isle пишет:
Другое дело - не знаю как написать простую функцию для одновременной распечатки самого дерева и выборки путей категорий/подкатегорий... Пришлось клепать мега-функцию, вернее даже две: распечатка самого дерева и выборка (жестко завязанная по вложенности) путей категорий/подкатегорий, простенький примерчик для наглядности который привел выше.
Если знаете как можно всё объединить в кучу для минимизации (оптимизации?) кода и без искусственных ограничений вложенности, был бы очень благодарен, а то уже мозг просто кипит, скоро взорвусь
Вот это все говорит, как раз о неверном подходе. Попробуйте написать элементарный класс и увидите как все станет проще.
----- "Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог
Champion
Отправлено: 12 Июня, 2010 - 09:26:26
Активный участник
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
isle пишет:
можно сделать любую просто добавив еще циклов.
Не надо. А если ты не знаешь заранее вложенность? Если она потенциально не ограничена?
Вот тут примерно то, что тебе нужно http://forum.php.su/topic.php?fo...pic=2497&p=1 .
Из таблицы в БД (parent_id, id, title) строится иерархическая штуковина.
Joo пишет:
Это очень просто реализуется на классах
А причем тут вообще классы?
Joo
Отправлено: 12 Июня, 2010 - 10:28:17
Гость
Покинул форум
Сообщений всего: 99
Дата рег-ции: Нояб. 2009 Откуда: Казахстан
Помог: 1 раз(а)
Champion пишет:
А причем тут вообще классы?
При том, что создание дерева, именно дерева, реализуется проще классами, нежели массивами. Хотя я вроде бы не где не утверждал, что нельзя построить как не будь иначе, чтобы вызывать недовольство, у каждого свое мнение на сей счет, и пусть каждый делает как ему нравится.
Да к стати, пример, что Вы разместили в самом низу здесь:
Это даже, простите, не примерно дерево, и не какой иерархической "штуковины" там не строится. Все что делает этот код - загружает содержимое из БД в двумерный массив, хотя справедливости ради стоит заметить, что из него таки можно построить дерево.
----- "Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог
Phantik
Отправлено: 12 Июня, 2010 - 10:32:13
Посетитель
Покинул форум
Сообщений всего: 305
Дата рег-ции: Июнь 2009
Помог: 0 раз(а)
Недавно на собеседовании делал похожую хрень. Про рекурсию слышал что-нибудь?
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
Joo пишет:
При том, что создание дерева, именно дерева, реализуется проще классами
Оно реализуется, во-первых, списками. В PHP для него очень удачно подходяит массивы, где индекс - это id узла, а элемент - массив дочерних узлов в таком же виде (свой id и список дочерних). Строится такая структура из обычной таблицы pid - id очень просто. Как - написано в той теме, ссылку на которую я привел и в предыдущем посте Фантика.
Joo пишет:
я вроде бы не где не утверждал, что нельзя построить как не будь иначе
Я не спорю. Но ты предложил классы. Мое личное мнение, что сувать ООП в те места, где оно не нужно, не нужно. Здесь, с моей точки зрения, оно не нужно. И я спросил, каким образом ты планируешь его тут применить, а не выражал недовольство.
Joo пишет:
Это даже, простите, не примерно дерево
Это то, из чего дерево элемнтарно строится.
Joo пишет:
загружает содержимое из БД в двумерный массив
Ты видишь минусы такого представления?
isle
Отправлено: 12 Июня, 2010 - 15:47:30
Гость
Покинул форум
Сообщений всего: 111
Дата рег-ции: Окт. 2009 Откуда: Казахстан, Алматы
Помог: 0 раз(а)
Наконец-то сообразил, как здесь на форуме сделать наглядную распечатку дерева, а то всё у меня форсатирование съедалось Вот готовое дерево:
У меня такая же проблема, как и у Фантика, он тоже отдельно получает путь к категории и саму категорию (имя и расположение, тем более формируя целую кучу запросов и массивов, что значительно скажется на каталоге в 50-100 катов/подкатов с очень высокой посещалкой...), я же пытаюсь без всяких запросов в БД и лишней проходкой по массивам взять сразу всё, но не выходит, поэтому я сначала получаю один массив, из которого делаю выборку путей, потом второй - дерево, из самого дерева получаю саму категорию (расположение) - это не рационально: создавать несколько n-вложенных массивов и с каждым в отдельности работать, чтоб потом получить еще один массив - обработанное готовое дерево с путями к категориям и их расположением.
Вроде как смысл понимаю, но логику как всё разом забрать и уменьшить код со ста строчек до 10 - никак не пойму... опять всё возвращаюсь к тому, что приходится создавать и обрабатывать несколько массивов, но хоть без лишних запросов в БД (2 основных как минимум - пути и структуру, т.е. иерархию - расположение в дереве).
Joo, извините, не в обиду будет сказано и никак не в придирку... Просто смотрите, если мне писать класс, то ведь он же должен состоять из каких функций, так? Вот те функции, которые я инклюдом получаю из другого файла, я точно также получу их же и из класса, но только с лишним гемороем: мне проще функцию написать, чем сидеть с классом разбираться, который из этой же функции и будет состоять... То есть масло маслянное с перцем и горщицей
Phantik, спасибо за пример, но реализация очень корявая и хуже (? - на мой взгляд, извиняюсь), чем то, что я сделал по другому примерчику (позаимствовал идею у одного блогера и 5 его строчек превратил в сто , теперь занимаюсь обратным процессом).
Champion, спасибо за ссыль, курю... Пока ничего путного не встретил, но есть там парочка ссылок на деревья, сейчас за кофейком выпью их, может, там примерчики что мне нужны...
Ребята, спасибо за помощь.
Если кому интересно, то вот так я пока это хозяйство за сегодня реализовал (сначала пути вытащил, потом само дерево распечатал, эх, совместить и упростить код никак пока не выходит, нужен какой-то примерчик хоть бы на пальцах, чтоб логику объединения функций понять):
if ($begin_i==1) $list .= "\t\t </ul>\n\t\t </li>\n";
$begin_i = 0;
}
return $list;
}
Надеюсь, пример полного кода обработки дерева кому-то еще поможет, как наглядное пособие. Еще раз спасибо за обсуждение, пошел курить деревья дальше.
Joo
Отправлено: 12 Июня, 2010 - 16:14:14
Гость
Покинул форум
Сообщений всего: 99
Дата рег-ции: Нояб. 2009 Откуда: Казахстан
Помог: 1 раз(а)
isle пишет:
Joo, извините, не в обиду будет сказано и никак не в придирку...
Да не чего страшного, просто я предложил, вас это не устраивает. Не каких обид земляк
Если делать по "простому" то Champion предложил вполне рабочий вариант, который вполне подходит под вашу задачу, нужно только написать функцию для его вывода, кстати у Phantik можно взять функцию MakeTree, как пример, которая рекурсивно пройдется по веткам.
Удачи.
----- "Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог
Champion
Отправлено: 12 Июня, 2010 - 16:20:13
Активный участник
Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008 Откуда: Москва
Помог: 57 раз(а)
А стоп, так так дерево уже есть и нужно просто его обойти и вывести путь от корня до низу?
Вот такая штука для твоего дерева подойдет. Но как я понял, ты сначала это дерево сформировал из простого массива pid-id-info? Этого не обязательно делать. Даже и не нужно. (Добавление)
isle пишет:
тем более формируя целую кучу запросов и массивов, что значительно скажется на каталоге в 50-100 катов/подкатов с очень высокой посещалкой...), я же пытаюсь без всяких запросов в БД и лишней проходкой по массивам взять сразу всё
Запрос у Фантика всего один. А массив можно сформировать не только из БД, а не важно откуда. Можно формировать его не целиком... Смотря, какая задача на самом деле. Исходя из постановки "У меня получилось дерево, его надо вывести", мы вроде ответили. Но вопрос, откуда оно у тебя взялось, это дерево? (Добавление)
Joo пишет:
Если делать по "простому"
Всегда надо делать по-простому. Оно часто и эффективнее
Joo
Отправлено: 12 Июня, 2010 - 16:33:41
Гость
Покинул форум
Сообщений всего: 99
Дата рег-ции: Нояб. 2009 Откуда: Казахстан
Помог: 1 раз(а)
Champion пишет:
Всегда надо делать по-простому. Оно часто и эффективнее
На простом примере, но когда задача усложняется, то по простому не получиться.
----- "Им будет не просто, тем кто полагается на истину авторитета, вместо того чтобы полагаться на авторитет Истины"
Джеральд Месси, Египтолог
isle
Отправлено: 12 Июня, 2010 - 18:38:16
Гость
Покинул форум
Сообщений всего: 111
Дата рег-ции: Окт. 2009 Откуда: Казахстан, Алматы
Помог: 0 раз(а)
Champion пишет:
А стоп, так так дерево уже есть и нужно просто его обойти и вывести путь от корня до низу?
Не совсем верно, иначе бы это упростило задачу , пример моей функции вывода дерева можно под спойлером посмотреть. Мне нужно не только пройтись от верхнего уровня до нижнего, но и вернуться опять к верхнему в дереве... Нужно учесть $level = 0; затем его плюсовать или минусовать - вроде как всё понятно, но вверх его поднимаю без проблем, а спустить обратно (к главным категориям) не получается - категории замещают друг друга. Наделал кучу разных вариантов и не работает, как должно, вот и приходится пока не по дереву бегать, а еще доп. массивы для выборки путей, чтоб потом в дереве реплейсом поменять имя категории на готовый путь.
Но пришла идея не создавать еще один мега-массив для обработки путей, а ... Сейчас думаю так попробоввать: Если опускаемся на уровень вниз (каунтом уровни не получится подсчитать - подсчитывается только то, что на уровень ниже, а это не то), то создаём массив путей, типа:
# В самом начале: $path[0] = "$domain/";
# Затем в дереве при переходе в глубь...
$lvl++;
$path[$lvl] = $path[$lvl-1].'/';
...
и так по нарастающей от уровня...
+ текущая директория = полный путь.
Примерчик чертовски простенький и интересненький... сейчас попробую по этой схемке покрутить массив, спасибо. В принципе, если бегать несколько раз по двумерному массиву, то даже и дерево тогда не нужно, зря строил, а сразу вытащить всё одним махом получится Я поначалу так и начал, но столкнулся с проблемкой как мне массив перестроить после удаления пустых элементов ансетом, чтоб сотню категорий постоянно не пересчитывать, а: 100, 99, 98 ... (иначе коунт($арр) их тоже считает) - не смог поначалу и решил, что проще будет еще мега-массив сделать, но так только еще больше нагромоздил скриптов
Возьму-ка я денек еще, через день-два отпишусь как и что сделал, пока нужно еще самому попробовать покрутить это, теперь больше вник в суть деревьев. Эх, век живи - век учись
Цитата:
Но как я понял, ты сначала это дерево сформировал из простого массива pid-id-info? Этого не обязательно делать.
Верно, сначала массив взял типа
$cats[$id][$pid][$link];
, отсортировал, почистил и т.д., а из него уже получил дерево. При этом $info (т.е. $link) = "<ul><li><img scr="icon"><a href="/catname/">text</a></li></ul>" вот в таком приметиве выглядит, он в разы больше, а это для примера.
затем уже в процессе прегами и реплейсами меняю href на полный путь.
Спасибо, вроде понятней стало, разобрался, теперь нужно попробовать вживую наклепать.
JustUserR
Отправлено: 13 Июня, 2010 - 13:09:21
Активный участник
Покинул форум
Сообщений всего: 8715
Дата рег-ции: Июнь 2009
Помог: 17 раз(а)
isle пишет:
Но пришла идея не создавать еще один мега-массив для обработки путей, а ... Сейчас думаю так попробоввать: Если опускаемся на уровень вниз (каунтом уровни не получится подсчитать - подсчитывается только то, что на уровень ниже, а это не то), то создаём массив путей, типа:
Для получения универсальности в вашей задаче необходимо использовать рекурсивный подход к построению дерева - который в общем случае делается по следующему принципу У вас имеется набор данных которые связаны собой отношениями как родители и потомки - вы сохраняете их в одномерных массив таким образом чтобы каждый элемент имел свой идентификатор и ссылку на родительский элемент и сами выводимые данные - после чего применяете к ним функцию http://forum.php.su/topic.php?fo...65891#1271165891 которая построит вам многомеррый хеш-массив по принципу что в ключе массива лежит идентификатор элемента - а в соответствующем значении ссылка на потомков или null Далее вы можете простой рекурсивно обходить это дерево в нужном порядке - и по идентификатору элемента извлекать выводимые данные из начального одномерного массива
----- Сделать можно все что угодно - нужно только старание, терпение и хороший поисковик
Безлимитный web-хостинг от 15 рублей за 40 МБ дискового пространства - http://ihost[dot]oks71[dot]ru/
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.