0

I have multiple strings similar to:

$str = "/One/Two";
$str2 = "/One/Two/Flowers";
$str3 = "/One/Two/Grass";
$str4 = "/One/Another/Deeper";
$str5 = "/Uno/Dos/Cow";

I want to split it into a deep nested array that looks similar to the following:

Array
(
    [One] => Array 
    (
        [Two] => Array
        (
            [Flowers] => 
            [Grass] => 
        )    
        [Another] => Array
        (
            [Deeper] => 
        )           
    )   
    [Uno] => Array 
    (
        [Dos] => Array
        (
            [Cow] => 
        )             
    )         
)

2 Answers 2

5

This should do it:

$strings = array(
    "/One/Two",
    "/One/Two/Flowers",
    "/One/Two/Grass",
    "/One/Another/Deeper",
    "/Uno/Dos/Cow"

);

$result = array();

foreach($strings as $string) {
    $parts = array_filter(explode('/', $string));

    $ref = &$result;
    foreach($parts as $p) {
        if(!isset($ref[$p])) {
            $ref[$p] = array();
        }
        $ref = &$ref[$p];
    }
    $ref = null;
}

print_r($result);

Working example:

http://codepad.org/GmAoXLXp

Sign up to request clarification or add additional context in comments.

3 Comments

I think some of the code in this solution is a bit redundant but mainly I am just bitter at the lack of recognition for a couple second late answer =\
@erisco, if by redundant you refer to the isset part, it actually is necessary, referencing an uninitialized variable will throw a notice. And setting $ref to null at the end prevents references from showing up in the final array. Other than that, our codes seem to be pretty identical. +1 for that :)
I +1 you as well, thanks :) PHP doesn't care if you reference a variable that has not yet been declared. Instead of throwing a notice it will just initialize it to null. Tricks of the trade! Now don't go neglecting to test for $_POST and $_GET keys...
1

Something like this should work. I couldn't think of any nice functional way to build the structure, so I fell back to a couple foreach loops.

<?php

$strings = array(
    '/One/Two',
    '/One/Two/Flowers',
    '/One/Two/Grass',
    '/One/Another/Deeper',
    '/Uno/Dos/Cow'
);

$paths = array_map(
    function ($e) {
        return explode('/', trim($e, '/'));
    },
    $strings
);

$pathStructure = array();

foreach ($paths as $path) {
    $ref =& $pathStructure;
    foreach ($path as $dir) {
        $ref =& $ref[$dir];
    }
}
unset($ref);

print_r($pathStructure);

1 Comment

Thank you for taking the time with this question erisco, I already put my checkmark on Tatu's, but your method works as well. I will study both and figure out how this was done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.