7

I have string:

Main.Sub.SubOfSub

And some kind of data, may be a string:

SuperData

How I can transform it all to this array above?

Array
(
[Main] => Array
    (
        [Sub] => Array
            (
                [SubOfSub] => SuperData
            )

    )

)

Thanks for help, PK

PiKey
  • 567
  • 4
  • 23
  • $tmp_array = explode('.', $your_string); Then iterate through the $tmp_array and create your $k array – djot Dec 16 '11 at 16:34
  • Have a look at http://php.net/manual/en/function.explode.php and http://php.net/manual/en/function.implode.php and you are almost home. – Cyclonecode Dec 16 '11 at 16:38
  • Similar question, just for an `stdClass` object, not array: [Array to object](http://stackoverflow.com/q/11188563/367456). – hakre Jun 25 '12 at 15:06

2 Answers2

11

Given the values

$key = "Main.Sub.SubOfSub";
$target = array();
$value = "SuperData";

Here's some code I have lying around that does what you need¹:

$path = explode('.', $key);
$root = &$target;

while(count($path) > 1) {
    $branch = array_shift($path);
    if (!isset($root[$branch])) {
        $root[$branch] = array();
    }

    $root = &$root[$branch];
}

$root[$path[0]] = $value;

See it in action.

¹ Actually it does slightly more than that: it can be trivially encapsulated inside a function, and it is configurable on all three input values (you can pass in an array with existing values, and it will expand it as necessary).

Jon
  • 396,160
  • 71
  • 697
  • 768
5

Like Jon suggested (and being asking feedback for in chat), a reference/variable alias is helpful here to traverse the dynamic stack of keys. So the only thing needed is to iterate over all subkeys and finally set the value:

$rv = &$target;
foreach(explode('.', $key) as $pk)
{
    $rv = &$rv[$pk];
}
$rv = $value;
unset($rv);

The reference makes it possible to use a stack instead of recursion which is generally more lean. Additionally this code prevents to overwrite existing elements in the $target array. Full example:

$key = "Main.Sub.SubOfSub";
$target = array('Main' => array('Sub2' => 'Test'));
$value = "SuperData";

$rv = &$target;
foreach(explode('.', $key) as $pk)
{
    $rv = &$rv[$pk];
}
$rv = $value;
unset($rv);

var_dump($target);

Output:

array(1) {
  ["Main"]=>
  array(2) {
    ["Sub2"]=>
    string(4) "Test"
    ["Sub"]=>
    array(1) {
      ["SubOfSub"]=>
      string(9) "SuperData"
    }
  }
}

Demo

Related Question(s):

Community
  • 1
  • 1
hakre
  • 178,314
  • 47
  • 389
  • 754