views:

46

answers:

1

So here's the input:

$in['a--b--c--d'] = 'value';

And the desired output:

$out['a']['b']['c']['d'] = 'value';

Any ideas? I've tried the following code without any luck...


$in['a--b--c--d'] = 'value';
// $str = "a']['b']['c']['d";
$str = implode("']['", explode('--', key($in)));
${"out['$str']"} = 'value';
+7  A: 

This seems like a prime candidate for recursion.

The basic approach goes something like:

  1. create an array of keys
  2. create an array for each key
  3. when there are no more keys, return the value (instead of an array)

The recursion below does precisely this, during each call a new array is created, the first key in the list is assigned as the key for a new value. During the next step, if there are keys left, the procedure repeats, but when no keys are left, we simply return the value.

$keys = explode('--', key($in));

function arr_to_keys($keys, $val){
    if(count($keys) == 0){
        return $val;
    }
    return array($keys[0] => arr_to_keys(array_slice($keys,1), $val));
}

$out = arr_to_keys($keys, $in[key($in)]);

For your example the code above would evaluate as something equivalent to this (but will work for the general case of any number of -- separated items):

$out = array($keys[0] => array($keys[1] => array($keys[2] => array($keys[3] => 'value'))));

Or in more definitive terms it constructs the following:

$out = array('a' => array('b' => array('c' => array('d' => 'value'))));

Which allows you to access each sub-array through the indexes you wanted.

Mark E
Yeah, something like it. It deserves commentary. +1 anyway.
Ian
Would be good to comment on what you are doing... +1
gahooa
Works great! Is there no way to create the multi-dimensional array using ${\'out['a']['b']['c']['d']\'} = 'value'; ?
Matt
@Matt, you can do that using `eval`, but I wouldn't recommend it. something like `eval("\$out['a']['b']['c']['d'] = 'value';")` would be equivalent.
Mark E
Thanks for the help
Matt