Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building paths from multidimensional array in PHP

I have an array such as:

$tree = array(
    'folder_1' => array(
        'folder_1_1',
        'folder_1_2' => array(
            'folder_1_2_1',
            'folder_1_2_2'
        ),
        'folder_1_3'
    ),
    'folder_2' => array(
        'folder_2_1' => array(
            'folder_2_1_1' => array(
                'folder_2_1_1_1',
                'folder_2_1_1_2'
            )
        ),
    )
);

And I'm trying to build an array of paths:

$paths = array(
    'folder_1',
    'folder_1/folder_1_1',
    'folder_1/folder_1_2',
    'folder_1/folder_1_2/folder_1_2_1',
    'folder_1/folder_1_2/folder_1_2_2',
    'folder_2',
    'folder_2/folder_2_1',
    ...
);

I can't seem to find a way to achieve this. The problem I encounter is that folder names can be array keys, but also array elements.

This is what I have done so far, but I'm not near a solution...

$paths = transform_tree_to_paths($trees);

function transform_tree_to_paths($trees, $current_path = '', $paths = array())
{

    if (is_array($trees)) {
        foreach ($trees as $tree => $children) {
            $current_path .= $tree . '/';
            return transform_tree_to_paths($children, $current_path, $paths);
        }
        $paths[] = $current_path;
        $current_path = '';
    } else {
        $paths[]  = $trees;
    }

    return $paths;
}
like image 965
skirato Avatar asked Apr 21 '16 11:04

skirato


1 Answers

How about something like this?

function gen_path($tree, $parent=null) {
    $paths = array();

    //add trailing slash to parent if it is not null
    if($parent !== null) {
        $parent = $parent.'/';
    }

     //loop through the tree array
     foreach($tree as $k => $v) {
        if(is_array($v)) {
            $currentPath = $parent.$k;
            $paths[] = $currentPath;
            $paths = array_merge($paths, gen_path($v, $currentPath));
        } else {
            $paths[] = $parent.$v;
        }
    }

    return $paths;
}

You were headed in the right direction, but missed the mark a bit. The return statement before the recursive function call in your function caused everything after the foreach loop to never be called.

like image 88
Baconics Avatar answered Nov 19 '22 17:11

Baconics