Подскажите, пожалуйста, как построить дерево из строк? Имеется массив:
$arr = [
'FOLDER1',
'FOLDER2',
'FOLDER2|FOLDER3',
'FOLDER2|FOLDER4',
'FOLDER2|FOLDER4|FOLDER5',
'FOLDER6|FOLDER7',
'FOLDER8',
'FOLDER8|FOLDER9'
];
Нужно получить массив вида:
$output = [
[
"short" => "FOLDER1",
"full" => "FOLDER1",
"sub_folders" => []
],
[
"short" => "FOLDER2",
"full" => "FOLDER2",
"sub_folders" => [
[
"short" => "FOLDER3",
"full" => "FOLDER2|FOLDER3",
"sub_folders" => []
],
[
"short" => "FOLDER4",
"full" => "FOLDER2|FOLDER4",
"sub_folders" => [
[
"short" => "FOLDER5",
"full" => "FOLDER2|FOLDER4|FOLDER5",
"sub_folders" => []
]
]
]
]
],
[
"short" => "FOLDER6",
"full" => "FOLDER6",
"sub_folders" => [
[
"short" => "FOLDER7",
"full" => "FOLDER6|FOLDER7",
"sub_folders" => []
]
]
],
[
"short" => "FOLDER8",
"full" => "FOLDER8",
"sub_folders" => [
[
"short" => "FOLDER9",
"full" => "FOLDER8|FOLDER9",
"sub_folders" => []
]
]
]
];
Алгоритм в принципе не хитрый, подобные задачи в принципе встречались тут не единожды.
Следует просматривать каждую строку отдельно, и разбивать ее с помощью explode() на части. Результирующий массив для упрощения алгоритма можно сделать изначально вида ['full' => "", 'subfolders' => []].
Дальше для каждой строки надо строить дерево. Тут принцип прост и встречается (в т.ч. на этом ресурсе) не редко. Вы просто идете по массиву, и при этом сохраняете ссылку на предыдущий элемент, вроде foreach($data as $d){ .....; $prev = &$d; } и имеете доступ к родительскому элементу на каждой итерации. Это позволит простым циклом строить ветку дерева, ведь вам именно это и требуется.
$result = ['subfolders' => [], 'full' => ""];
foreach($arr as $s){
$data = explode('|', $s);
$p = &$result;
foreach($data as $k){
if(!array_key_exists($k, $p['subfolders'])){
$p['subfolders'][$k] = [ // добавили дочерний элемент
'short' => $k,.
'full' => $p['full']."|$k",.
'subfolders' => []
];
}
$p = &$p['subfolders'][$k]; // ссылка на родителя
}
}
$result = $result['subfolders'];
Единственное, в данной реализации полный путь начинается с |. Думаю, с этим вы и сами разберетесь.
Как вариант
foreach($arr as $row){
foreach( explode('|',$row) as $val){
# здесь генерим массив с проверкой на subfolders
$tmp=['short'=>$val,'short'=>$val];
if(count($val)==2){}
if(count($val)==3){}
$out[]=$tmp;
}
}
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости