Рекурсивный анализ многомерного массива php, внесение изменений и возврат результата

#php #arrays #recursion #multidimensional-array

#php #массивы #рекурсия #многомерный массив

Вопрос:

Я хотел бы проанализировать массив, получить некоторую информацию и вернуть новый массив, но рекурсивно я не знаю, как это сделать.

Вот пример массива:

 $arr= array ( 
                0 => array ( 
                            'id'=> 0,
                            'dir_name' => '', 
                            'children' => array ( 
                                36 => array ( 
                                                'id'=>36,
                                                'dir_name' => 'dir 36', 
                                                'children' => array ( 
                                                    92 => array ( 
                                                                    'id'=>92,
                                                                    'dir_name' => 'dir 92', 
                                                                    'children' => array ( 
                                                                        93 => array ( 
                                                                                        'id'=>93,
                                                                                        'dir_name' => 'dir 93', ), ), ), 
                                                    94 => array ( 
                                                                    'id'=>94,
                                                                    'dir_name' => 'dir 94', 
                                                                    'children' => array ( 
                                                                        95 => array ( 
                                                                                        'id'=>95,
                                                                                        'dir_name' => 'dir 95', ), ), ), ), ), ), ), );
  

Вот моя функция:

 function all_dir($array,$id_selected=0,$pos=0,$tab_pos=[]) 
{
  $flat= [];

  foreach($array as $k=>$value) 
  {

    if (is_array($value)) 
        $flat = array_merge($flat, all_dir($value, $id_selected,$pos,$tab_pos));
    else 
    {
        if($k=="id")
        {
            $option='<option value="'.$value.'"';
            if($value==$id_selected)
                $option .=" selected ";

        }

        if($k=="dir_name")
        {
            $flat[] = $value;
            $tab_pos[$pos]=$value;

            $val='';
            for($i=0; $i<=$pos; $i  )
            {
                $val .= $tab_pos[$i].'/';
            }

            $option .='>'.$val.'</option>';

            echo $option;

            $pos  ;
        }


    }

  }
  return $flat;
}
  

Пример html-кода:

 <html>
    <body>

        <select name="" id="">
            <?php
                all_dir($arr, 93);
            ?>
        </select>
    </body>
</html>
  

Что я получаю:

 <select id="" name="">
<option value="0">/</option>
<option value="36">/dir 36/</option>
<option value="92">/dir 36/dir 92/</option>
<option selected="" value="93">/dir 36/dir 92/dir 93/</option>
<option value="94">/dir 36/dir 94/</option>
<option value="95">/dir 36/dir 94/dir 95/</option>
</select>
  

Чего я хочу:

all_dir() возвращает массив типа (и не отображает некоторые параметры html-кода):

  [
        "0" =>"/",
        "36" =>"/dir 36/",
        "92" =>"/dir 36/dir 92/",
        "93" =>"/dir 36/dir 92/dir 93/",
        "94" =>"/dir 36/dir 94/",
        "95" =>"/dir 36/dir 94/dir 95/",
]
  

Комментарии:

1. Попробуйте использовать поиск в глубину (DFS)

2. У меня нет проблем с анализом моего массива, но как я могу вернуть свой конечный массив в моей рекурсивной функции 🙂

Ответ №1:

Вы хотите преобразовать одну структуру массива в другую. Это можно сделать многими способами.

Я решил разделить вашу функцию на две части: первая get_dir рекурсивно проходит через массив и захватывает важные данные ( id и dir_name ), а вторая get_dir_root преобразует этот непосредственный формат в формат, который вы ожидаете.

Также я удалил $id_selected , $pos , $tab_pos аргументы, поскольку вы не используете его в новой версии.

 function get_dir($array, $names = [])
{
    $ret = [];

    foreach ($array as $k => $v)
    {
        $id = $v['id'];
        $name = $v['dir_name'];

        $ret[$id] = $names;
        $ret[$id][] = $name;

        if (!empty($v['children']))
        {
            $xret = get_dir($v['children'], $ret[$id]);

            foreach ($xret as $kk => $vv)
            {
                $ret[$kk] = $vv;
            }
        }
    }

    return $ret;
}

function get_dir_root($array)
{
    $ret = [];

    foreach (get_dir($array) as $k => $v)
    {
        $ret[$k] = implode ('/', $v);

        if ($ret[$k] == '')
            $ret[$k] = '/';
        else
            $ret[$k] .= '/';
    }

    return $ret;
}
  

Рабочий пример

Комментарии:

1. ключевым моментом было разделение на 2 функции. спасибо за вашу помощь и пояснения 🙂