Рекурсивный цикл по многомерному для создания плоского массива

У меня есть многомерный массив, который выглядит так:

$trees = array(
    array(
        'name' => 'Parent',
        '__children' => array(
            array(
                'name' => 'Child'
            ),
            array(
                'name' => 'Second Child'
            )
        )
    )
);

Глубина массива неизвестна, и мне нужно рекурсивно сгладить его. Так это выглядит примерно так:

array(
  array(
    'name' => 'Parent' 
  ),
  array(
    'name' => 'Child' 
  ),
  array(
    'name' => 'Second Child' 
  )
)

Я думал, что-то вроде этого может работать:

public function flattenTree($trees, $tree = array())
{
    foreach($trees as $item){
        //$i = 1, 2, then 3
        $i = count($tree);
        $tree[$i] = array('name' => $item['name']);
        if(isset($item['__children']))
            $this->flattenTree($item['__children'], $tree);
    }
    return $tree;
}

Но это только дает мне :(

Array
(
    [0] => Array
        (
            [name] => Parent
        )

)

Я не уверен, как это сделать. Является ли это возможным?

В качестве бонуса мне действительно нужен выходной массив, чтобы он выглядел следующим образом (обратите внимание, что имя изменилось) :)

array(
  array(
    'name' => 'Parent' 
  ),
  array(
    'name' => 'Parent Child' 
  ),
  array(
    'name' => 'Parent Second Child' 
  )
)

Большое спасибо за помощь в этом. Ждем решений. Я в тупике!

 Mohamed Navas18 нояб. 2012 г., 19:30
Вы можете't указать элемент массива без индекса. Я'я уверен, что вы получили правильный вывод сейчас
 Pankrates18 нояб. 2012 г., 22:13
Правильно ли я понял из вашего поста, что вы действительно хотите вставить строку перед исходным именем родителя?родитель» имя ребенка?
 Mike18 нояб. 2012 г., 20:54
@ mohamed да. По какой-то причине вывод не содержит детей
 John Conde18 нояб. 2012 г., 19:24
 Mike18 нояб. 2012 г., 22:14
@pankrates это правильно. Я хотел бы, чтобы первая часть работала. Но тогда мне нужно добавить имя, как показано в последнем блоке кода.
 Mike18 нояб. 2012 г., 21:45
@JohnConde есть ли шанс, что вы можете взять пример по этой ссылке и применить его здесь? Я не уверен, как именно это будет работать, особенно с созданием полного имени на основе дерева.
 Mohamed Navas18 нояб. 2012 г., 19:32
ваша проблема отсутствует дочерний элемент из массива?

Ответы на вопрос(3)

я дал этому шанс, и хотя это может быть не самое чистое решение, я думаю, что оно должно выполнить работу:

function flattenRecursive(array &$flat, $parentkey, array $nested){

    $flag       = true;
    $prepend    = '';

    foreach( $nested as $k => $val ){
        if( is_array($val) ){

            if ( $k == '__children' && $flag) {
                $prepend = end($flat);
                $flag = true;
            } else {
                $flag = false;
            }

            flattenRecursive($flat, $prepend , $val);

        } else {

            $flat[] = $parentkey . ' ' . $val;

        }
    }
}

function flatten(array $nested){
    $flat = array();
    flattenRecursive($flat, '', $nested);
    return $flat;
}

На массиве тестов (с дополнительной вложенностью для дополнительного тестирования) следующим образом

$trees = array(
            array(
                'name' => 'Parent',
                '__children' => array(
                    array(
                        'name' => 'Child',
                        '__children' => array(
                            array(
                                'name' => 'Nest One'
                            ),
                            array(
                                'name' => 'Nest Two'
                            )
                        )
                    ),
                    array(
                        'name' => 'Second Child'
                    )
                )
            )
        );

$result = flatten($trees);

var_dump из$result выглядит следующим образом

array(5) {
  [0]=>
  string(7) " Parent"
  [1]=>
  string(13) " Parent Child"
  [2]=>
  string(22) " Parent Child Nest One"
  [3]=>
  string(22) " Parent Child Nest Two"
  [4]=>
  string(20) " Parent Second Child"
 }

Надеюсь, это было то, что вы искали

 Mike19 нояб. 2012 г., 00:09
Привет, Панкратеш, я думаю, что вы что-то здесь делаете. Однако это не работает для меня, потому что массив более сложен, чем этот и использует foreach ($ nested как $ k => $ val) отбрасывает вещи. Можете ли вы перевести это так, чтобы вместо него использовался foreach ($ nested как $ item)?
 Mike19 нояб. 2012 г., 18:17
Смотрите мой ответ, еще раз спасибо за ваши усилия! Это очень помогло.
 Pankrates19 нояб. 2012 г., 08:47
Не могли бы вы привести пример массива, в котором происходит сбой, и где он не работает? Трудно точно определить, что вы имеете в виду, без примера

код



$output_array = array();

$input_array  = array(
    array(
        'name'=>'Parent',
        '__children' => array(
            array(
                'name' => 'Child'
            ),
            array(
                'name' => 'Second Child'
            )
        )
    )
);

echo"<pre>";
print_r($input_array);
echo"</pre>";


function flatten($arr){
    global $output_array;
    if(is_array($arr)){
        foreach($arr as $key=>$value){
            if($key=="name" && !is_array($value)){
                $output_array[] = array($key=>$value);
            }
            elseif(is_array($value)){
                flatten($value);
            }
        }
    }
}

flatten($input_array);

echo"<pre>";
print_r($output_array);
echo"</pre>";

Выход

//Input array
Array
(
    [0] => Array
        (
            [name] => Parent
            [__children] => Array
                (
                    [0] => Array
                        (
                            [name] => Child
                        )

                    [1] => Array
                        (
                            [name] => Second Child
                        )

                )

        )

)

//Output Array
Array
(
    [0] => Array
        (
            [name] => Parent
        )

    [1] => Array
        (
            [name] => Child
        )

    [2] => Array
        (
            [name] => Second Child
        )

)
Решение Вопроса

что использовал что-то вроде этого, с большим вдохновением от ответа @Pankrates. Большое спасибо.

$trees = $multidimensionalArray;
$flat = array();
$postRepository->flattenRecursive($flat, $trees);
//$flat is now a flattened version of $multidimensionalArray
var_dump($flat);


public function flattenRecursive(array &$flat, array $nested, $parentPrepend = false)
{
    foreach( $nested as $item ){
        $flat[] = array(
            'name' => ($parentPrepend) ? $parentPrepend . '/' . $item['name'] : $item['name']
        );
        $prepend = $parentPrepend ? $parentPrepend . '/' . $item['name'] : $item['name'];
        if(isset($item['__children']))
            $this->flattenRecursive($flat, $item['__children'], $prepend);
    }
}

Ваш ответ на вопрос