MisterDebug
MisterDebug

Reputation: 923

Parsing multidimensional php array recursively, make a change and return a result

I would like to parse an array, get some informations and return a new array but recursively I don't know how do this.

Here an example of array:

$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', ), ), ), ), ), ), ), );

Here my function:

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;
}

A sample html code:

<html>
    <body>

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

What I get:

<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>

What I want:

all_dir() returns an array like (and don't display some options html code):

 [
        "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/",
]

Upvotes: 1

Views: 273

Answers (1)

Andrzej Budzanowski
Andrzej Budzanowski

Reputation: 1022

You want to transform one array structure to another. It can be done i many ways.

I decided to split your function in two, first one get_dir recursively travels through array and grabs important data (id and dir_name), and second get_dir_root that transforms that immediate format to format you expect.

Also i removed $id_selected, $pos, $tab_pos arguments, since you don't use it in new version.

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;
}

Working example

Upvotes: 1

Related Questions