Перевод массива из плоского вида в дерево

svr

Guest
Перевод массива из плоского вида в дерево

Есть массив вида
Код:
Array
(
    [1] => Array
        (
            [parent] => 
            [name] => index.html
        )
    [1] => Array
        (
            [parent] => video
            [name] => index.html
        )

    [2] => Array
        (
            [parent] => video/action
            [name] => index.html
        )

    [3] => Array
        (
            [parent] => music
            [name] => index.html
        )

    [4] => Array
        (
            [parent] => music/hard
            [name] => index.html
        )

    [5] => Array
        (
            [parent] => music/soft
            [name] => index.html
        )
мне необходимо преобразовать его в:
Код:
Array
(
    [main] => Array
        (
            [music] => Array
                (
                    [hard] => Array
                        (
                            [0] => index.html
                        )

                    [soft] => Array
                        (
                            [0] => index.html
                        )

                    [0] => index.html
                )

            [video] => Array
                (
                    [action] => Array
                        (
                            [0] => index.html
                        )

                    [0] => about.html
                    [1] => index.html
                )

        )

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

Кром

Новичок
>как сохранять индексы между вызовами функции так, чтобы все было корректно.

Очевидно, что передавая массив с индексами в качестве аргумента функции.
 

svr

Guest
Это понятно. Передам я, например, $index = 'music/hard' потом, например, explode('/', $index);, однако как в массив добавить результат рекурсси, как вызвать $array['music']['hard] = $result, не могу допетрить. Получить список индексов несложно, а как потом их по ним обратиться к соответствующему элементу массива?
 

Кром

Новичок
>однако как в массив добавить результат рекурсси
>как вызвать $array['music']['hard] = $result
>как потом их по ним обратиться к соответствующему элементу массива

Что то я не понимаю твоих терзаний. Ни одной фразы.

Идешь, стало быть foreache'ем по твоему массиву. Нашел элемент. Смотришь, есть ли у него родитель. Делишь его на фрагменты. Дальше вызываешь свою рекурсию. Проходишь по новому массиву. Если в корне нету родительского элемента, добавляешь его, если есть, идешь дальше по дереву.
 

svr

Guest
Вот например, в данный момент я ищу всех потомков music/soft, т.е. все страницы, находящиеся в рзделе music/soft. Сделать это совсем несложно, предположим, что все эти страницы найдены и находятся в массиве $pages. У меня есть переменная $index, которая передается как параметр функции и содержит текущего "родителя". В данный момент $index = 'music/soft'. Я ее могу разбить, преобразовать к любому виду. Теперь мне нужно этот массив $pages поместить в мой "древовидный массив" в индекс ['music']['soft']. В ситуации без рекурсии я бы просто написал $array['music']['soft'] = $pages;
Однако с рекурсией я не понимаю, как это синтаксически написать правильно: У меня есть переменная $index, есть массив страниц и древовидный массив.
Если я напишу $array[$index] = $pages, то в массив $array поместится элемент array['[music][soft']], а не array['music']['soft'].
 

Кром

Новичок
Я так понял лучше будет показать, чем объяснить. :)
Смысл примерно такой:

PHP:
function array_plain2tree($arr = '', $parent_name = '', $child_name = '')
{
	if (!is_array($arr))
		return 'Error! Not array';;

	$parent_array = $new_arr = array();
	foreach($arr as $key => $value)
	{
		if (is_array($value))
		{
			if (isset($value[$parent_name]) && is_string($value[$parent_name]))
				$parent_array = explode('/',$value[$parent_name]);
			else
				return 'Error! Undefined or wrong index: parent';

			if (isset($value[$child_name]) && is_string($value[$child_name]))
				$node_name = $value[$child_name];
			else
				return 'Error! Undefined or wrong index: name';

			$path_arr = array();			
			$parent_array = array_reverse($parent_array);
			
			for($i = 0; $i < count($parent_array); $i++)
			{
				if (0 != $i)				
					$path_arr = array($parent_array[$i] => $path_arr);
				else
					$path_arr = array(($parent_array[$i]?$parent_array[$i]:0) => $node_name);			
			}			
			
			$new_arr = array_merge_recursive($new_arr,$path_arr);
		}
		else
			return 'Error! Wrong array structure';
	}	
	return $new_arr;
}

print_r(array_plain2tree($plain_tree,'parent','name'));
 
Сверху