#php #recursion #hierarchical-data #virtuemart
#php #рекурсия #иерархические данные #virtuemart
Вопрос:
Моей отправной точкой является один массив с идентификаторами категорий и их родительских идентификаторов из таблицы категорий Virtuemart, вот так:
Массив ( [0] => Массив ( [id] => 1 [parent_id] => 0 [name] => Категория A ) [1] => Массив ( [id] => 2 [parent_id] => 1 [name] => Подкатегория A1 ) [2] => Массив ( [id] => 3 [parent_id] => 2 [name] => Подкатегория A1 ) [3] => Массив ( [id] => 4 [parent_id] => 1 [name] => Подкатегория A2 ) [4] => Массив ( [id] => 5 [parent_id] => 0 [name] => Категория B ) [5] => Массив ( [id] => 6 [parent_id] => 5 [name] => Подкатегория B ) )
Мне нужно иметь строку с полным путем к каждой последней дочерней категории, разделенным символом / (косая черта) между дочерними элементами и символом (запятая) между родителями первого уровня
Мой вывод должен быть:
Категория A / Подкатегория A1 / Подкатегория A1, Категория A / Подкатегория A2, Категория B/Подкатегория B
[РЕДАКТИРОВАТЬ] Я мог бы преобразовать начальный массив в этот
Массив ( [0] => Массив ( [id] => 1 [parent_id] => 0 [name] => Категория A [дочерние элементы] => Массив ( [0] => Массив ( [id] => 2 [parent_id] => 1 [name] => Подкатегория A1 [дочерние элементы] => Массив ( [0] => Массив ( [id] => 3 [parent_id] => 2 [name] => Подкатегория A1 ) ) ) [1] => Массив ( [id] => 4 [parent_id] => 1 [name] => Подкатегория A2 ) ) ) [1] => Массив ( [id] => 5 [parent_id] => 0 [name] => Категория B [дочерние элементы] => Массив ( [0] => Массив ( [id] => 6 [parent_id] => 5 [name] => Подкатегория B1 ) ) ) )
Ответ №1:
Учитывая следующий массив :
$array = Array(
"0" => Array
(
"id" => 1,
"parent_id" => 0,
"name" => "Category A"
),
"1" => Array
(
"id" => 2,
"parent_id" => 1,
"name" => "Subcategory A1"
),
"2" => Array
(
"id" => 3,
"parent_id" => 2,
"name" => "Sub-Subcategory A1"
),
"3" => Array
(
"id" => 4,
"parent_id" => 1,
"name" => "Subcategory A2"
),
"4" => Array
(
"id" => 5,
"parent_id" => 0,
"name" => "Category B"
),
"5" => Array
(
"id" => 6,
"parent_id" => 5,
"name" => "Subcategory B"
)
);
Что-то вроде этого :
$tabOfElements = array();
foreach($array as $element){
$tabOfElements[$element['id']] = (isset($tabOfElements[$element['parent_id']])?$tabOfElements[$element['parent_id']].'/':'').$element['name'];
}
$stringOfCategories = implode(',',$tabOfElements);
должно делать то, что вам нужно. Примечание: это работает, только если родительские категории всегда находятся ПЕРЕД дочерними в массиве.
Редактировать :
Чтобы получить только весь путь к последней дочерней категории, вы можете сделать :
$tabOfElements = array();
$elementsToDelete = array();
foreach($array as $element){
$tabOfElements[$element['id']] = (isset($tabOfElements[$element['parent_id']])?$tabOfElements[$element['parent_id']].'/':'').$element['name'];
if(isset($tabOfElements[$element['parent_id']]) amp;amp; !isset($elementsToDelete[$element['parent_id']])){
$elementsToDelete[$element['parent_id']] = $element['parent_id'];
}
}
$finalArray = array_diff_key($tabOfElements, $elementsToDelete);
$stringOfCategories = implode(',',$finalArray);
Это дало бы вам :
Category A/Subcategory A1/Sub-Subcategory A1,Category A/Subcategory A2,Category B/Subcategory B
ПРАВКА 2 :
Со вторым приведенным вами массивом вы можете использовать рекурсивную функцию типа :
function recursiveFunction($elementArray, $parentString = ''){
if(isset($elementArray['children']) amp;amp; !empty($elementArray['children'])){
foreach($elementArray['children'] as $keyChild=>$child){
$resultString .= recursiveFunction($child, $parentString.$elementArray['name'].'/').(($keyChild<count($elementArray['children'])-1)?',':'');
}
return $resultString;
}else{
return $parentString.$elementArray['name'];
}
}
$tabOfPaths = array();
foreach($array as $elementArray){
$tabOfPaths[] = recursiveFunction($elementArray);
}
$stringOfPaths = implode(',',$tabOfPaths);
echo $stringOfPaths;
Надеюсь, это поможет.
Комментарии:
1. На самом деле, это не совсем то, что вам нужно, поскольку он также предоставляет вам путь к каждой категории вместо всего последнего дочернего пути к категории.
2. РЕДАКТИРОВАТЬ: чтобы получить только путь к последней дочерней категории.
3. @Meeuuuhhhhh У меня не всегда родители предшествуют дочерним элементам, но я холодно преобразовываю начальный массив в иерархический, публикую отредактированный
4. @Andrea Parmeggiani Ну, хорошо, рекурсивная функция теперь является хорошим решением, я думаю, ответ отредактирован.