Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a standard array with key-value pairs - and I want to use the keys to transform it into a multi-dimensional array. The difficulty seems to be that I need to loop recursively the unknown number of new keys and turn them into a multi-dimensional array. In short, I want this:

$val[alfa.xray.uno] = "Some value";    
=> $val['alfa']['xray']['uno'] = "Some value";    

Example: (The code fails and also needs to handle N dimensions - but you get the idea..)

$arr['alfa.xray.uno'] = "Alfa X-Ray Uno";
$arr['alfa.yaho.duo'] = "Alfa Yaho Duo";
$arr['beta.xray.uno'] = "Beta X-Ray Uno";
$arr['beta.xray.duo'] = "Beta X-Ray Duo";
$arr['just-me'] = "Root-level item";

print_r( array_flat_to_multidimensional($arr) );

function array_flat_to_multidimensional($arr) {
    foreach($arr as $key=>$val) {
        $key = explode(".",$key);
        for($i=0; $i<count($key); $i++) {
            if($i==0) { $out[$key[$i]] = $val; }
            else if($i==1) { $out[$key[$i-1]][$key[$i]] = $val; }
            else if($i==2) { $out[$key[$i-2]][$key[$i-1]][$key[$i]] = $val; }
            else if($i==3) { $out[$key[$i-3]][$key[$i-2]][$key[$i-1]][$key[$i]] = $val; }
        }
    }
    return $out;
}

Perhaps RecursiveArrayIterator will do the trick?

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

You could use references to successively iterate through and build up the nested array structure:

$out = array();
foreach ($arr as $key=>$val) {
    $r = & $out;
    foreach (explode(".", $key) as $key) {
        if (!isset($r[$key])) {
            $r[$key] = array();
        }
        $r = & $r[$key];
    }
    $r = $val;
}
return $out;
share|improve this answer
    
Works out of the box. Thanks. –  Kristoffer Bohmann May 24 '11 at 5:14
add comment

use the recursion Luke

function ins(&$ary, $keys, $val) {
    $keys ? 
        ins($ary[array_shift($keys)], $keys, $val) :
        $ary = $val;
}

// test

$arr['alfa.xray.uno'] = "Alfa X-Ray Uno";
$arr['alfa.yaho.duo'] = "Alfa Yaho Duo";
$arr['beta.xray.uno'] = "Beta X-Ray Uno";
$arr['beta.xray.duo'] = "Beta X-Ray Duo";
$arr['just-me'] = "Root-level item";

$a = array();
foreach($arr as $k => $v)
    ins($a, explode('.', $k), $v);

print_r($a);
share|improve this answer
    
Excellent - just what I had in mind. Could it be boiled down to just one function? –  Kristoffer Bohmann May 22 '11 at 15:57
add comment

You can use a reference while walking though the array hierarchy levels:

function array_flat_to_multidimensional($arr) {
    $out = array();
    foreach ($arr as $compondKey => $val) {
        $ref = &$out;
        foreach (explode(".", $compoundKey) as $key) {
            if (!array_key_exists($key, $ref)) $ref[$key] = array();
            $ref = &$ref[$key];
        }
        $ref = $val;
    }
    unset($ref);
    return $out;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.