Построить дерево из строк

110
12 августа 2019, 07:40

Подскажите, пожалуйста, как построить дерево из строк? Имеется массив:

$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" => []
            ]
        ]
    ]
];
Answer 1

Алгоритм в принципе не хитрый, подобные задачи в принципе встречались тут не единожды.

Следует просматривать каждую строку отдельно, и разбивать ее с помощью 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'];

Единственное, в данной реализации полный путь начинается с |. Думаю, с этим вы и сами разберетесь.

Answer 2

Как вариант

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;
      }
}
READ ALSO
Перехватить адрес в joomla

Перехватить адрес в joomla

Нужно настроить работу роутера в джумла таким образом, что бы, если мы заходим по адресу siteru?iffjj=3 адрес в адресной строке сохранялся, не редиректило,...

114
Не корректные байты в xml

Не корректные байты в xml

При загрузке xml страницы в браузере выдает ошибку error on line 62164 at column 28: Input is not proper UTF-8, indicate encoding ! Bytes: 0x0F 0xE2 0x80 0x93

134
Laravel Curl Error: SSL read: errno -5961

Laravel Curl Error: SSL read: errno -5961

Обращаюсь к api через curl и иногда приходит вот такая ошибка: (SSL read: errno -5961)

97
Декодирование url в поисковом запросе

Декодирование url в поисковом запросе

Когда уважаемый посетитель вводит слово, скажем, «алкоголизьм» в текстовое поле поиска и нажимает кнопку «Поиск», то, при get-методе, в адресной...

115