Получит первые уровни дерева каталога массивом

программирование php

Простая, казалось бы, задача, но поставила в тупик Недовольство, огорчение
Собственно вот в чем дело. (упростил всё до минимума)
Есть массив двух первых уровней каталога:
$cats = array(
array(1,0, 'cat_1'), // array(id, parent_id, 'cat_title')
array(2,1, 'cat_1.1'),
array(3,1, 'cat_1.2'),
array(4,1, 'cat_1.3'),
array(5,0, 'cat_1'),
array(6,5,'cat_2.1'),
array(7,5,'cat_2.2'),
array(8,0,'cat_3'),
array(9,8,'cat_3.1')
);

Есть массив третьего уровня каталога с аналогичной структурой:
$lvl3 = array(
array(100,4,'some_cat1'), // array(id, parent_id, 'cat_title')
array(101,9,'some_cat2')
);
Задача - получить массив только первых уровней каталога отталкиваясь от значений parent_id третьего массива
Пробую делать так:
function tree($lines){
global $cats;
$arrCats = array();
for($i = 0; $i < count($lines); $i++){
foreach($cats as $key => $val){
if($val[0] == $lines[$i][1]){
$arrCats[] = $val;
}
}
}
if($arrCats[0][1] == 0){
print_r($arrCats); /* Это - тот самый уровень! Распечатать его можно, но вернуть этот массив не получается. Т.е. return $arrCats - пусто */
} else {
tree($arrCats);
}
}
$firstLvl = tree($lvl3); // Вызываем рекурсивную функцию

Как вернуть этот самый массив в переменную $firstLvl?


Примечание:
Epsiloncool (Epsilon S)
>>> пичалька ?))
Не то слово ))

Примечание:
Я так и знал, что звёзды на этой неделе не так расположились. На самом деле, первый массив лежит в базе. Второй, так сказать, у нас на руках. Я хотел избежать нескольких запросов к базе, чтоб добраться до первых уровней, поэтому вытащил все уровни все одним запросом, надеясь "разобраться" с ними переборами. Но кажется, что придётся напрягать базу ((

Примечание:
Epsiloncool (Epsilon S)
>>> Вы думаете, что база как-то сильно напряжётся от этого ?
Ну, если массив третьего уровня будет состоять из пары значений, то возможно, что и не напряжет. Но если этих третих третьих
уровней будет десяток, то десять раз стучаться в базу - как-то смущает.
Если вернуться с того, с чего начали, то есть правда вариант использовать не рекурсивную функцию, а вытащить сначала уровни второго уровня и
закинуть их опять в ту же функцию. Оно конечно работает, но уж больно код индусский получается )))
function tree($lines){
global $cats;
$arrCats = array();
for($i = 0; $i < count($lines); $i++){
foreach($cats as $key => $val){
if($val[0] == $lines[$i][1]){
$arrCats[] = $val;
}
}
}
return $arrCats;
}
$tmp = tree($lvl3); // тутачки второй уровень
$firstLvl = tree($tmp); // тут уже первый, то что надо.
Смотрю я на это и думаю, что второй бубен надо где-то брать )))

Примечание:
Epsiloncool (Epsilon S)
>>> Вытащите все элементы из БД и пройдитесь по нему рекурсией как я написал.
Так и попробую сделать. Только вот использоваться он будет часто, потому как это не изменения в меню... Этот процесс будет запускаться,
если пользователь будет искать продукт через поиск. Будет выводиться список найденных товаров и для корректного URL на страницу товара,
как раз не хватает этого гадского первого уровня. А так как на сайте используется ЧПУ, то без этого сложновато.
Ответы:
>>> Недовольство, огорчение
Возвращать не получится, так как в этот момент вы будете в глубине рекурсивного стека. Лучше всего выгрузить значение куда-нибудь в глобальную переменную (или свойство объекта), хотя как вариант - можно вытащить значение по ссылке (дополнительный параметр функции с амперсандом) или протащить возвращаемое значение через весь стек.
Я думаю, что лучше всего поделить это на две части. Первая часть - тупо перебор элементов в входном массиве. Вторая часть - рекурсивная функция, возвращающая наиболее старший элемент.
>>> Но кажется, что придётся напрягать базу ((
Вытащите все элементы из БД и пройдитесь по нему рекурсией как я написал. Это простой и эффективный способ (можно не только с третьего уровня искать, а вообще с любого). Можно конечно заморочиться и написать какой-то самооптимизирующийся алгоритм, который будет минимум данных из БД тащить, но оно этого не стоит. Проще банальное кэширование на результат повесить, ведь у вас меню не раз в минуту меняется, а где-то 1 раз в полжизни, а значит и этот тяжёлый алгоритм будет запускаться с такой же частотой.


13 лет назад

RPI.su - самая большая русскоязычная база вопросов и ответов. Наш проект был реализован как продолжение популярного сервиса otvety.google.ru, который был закрыт и удален 30 апреля 2015 года. Мы решили воскресить полезный сервис Ответы Гугл, чтобы любой человек смог публично узнать ответ на свой вопрос у интернет сообщества.

Все вопросы, добавленные на сайт ответов Google, мы скопировали и сохранили здесь. Имена старых пользователей также отображены в том виде, в котором они существовали ранее. Только нужно заново пройти регистрацию, чтобы иметь возможность задавать вопросы, или отвечать другим.

Чтобы связаться с нами по любому вопросу О САЙТЕ (реклама, сотрудничество, отзыв о сервисе), пишите на почту [email protected]. Только все общие вопросы размещайте на сайте, на них ответ по почте не предоставляется.