up vote 1 down vote favorite

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';
link|flag

I suspect you mean "consequence" instead of "output". – Ian Aug 22 at 15:13

1 Answer

up vote 7 down vote accepted

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.

link|flag
Yeah, something like it. It deserves commentary. +1 anyway. – Ian Aug 22 at 15:10
Would be good to comment on what you are doing... +1 – gahooa Aug 22 at 15:13
Works great! Is there no way to create the multi-dimensional array using ${\'out['a']['b']['c']['d']\'} = 'value'; ? – Matt Aug 22 at 15:16
@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 Aug 22 at 15:18
Thanks for the help – Matt Aug 22 at 15:22

Your Answer

 
or
never shown

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