There is no way to use all the values of $arr
without iterating over it.
I guess you don't want to write a foreach
loop but use some PHP function that does the iteration for you.
A simple solution that iterates two times over the array (behind the scene)
This is a possible solution:
$x = array_reduce(
array_reverse($arr),
function ($carry, $item) {
return [$item => $carry];
},
1
);
It generates the same result as:
$x = [];
$x['a']['b']['c']['d'] = 1;
Unfortunately it iterates over $arr
two times (array_reverse()
and array_reduce()
).
Another solution that generates a hierarchy of objects
Another approach that generates the required embedding using objects (stdClass
) instead of arrays:
$out = new stdClass;
array_reduce(
$arr,
function ($carry, $item) {
$v = new stdClass;
$carry->{$item} = $v;
return $v;
},
$out
);
It works using a single iteration over $arr
but it relies on the way the objects are handled in PHP to work (and this doesn't work with arrays).
PHP handles the objects in a way that makes them look like they are passed by reference. It's a common misconception that the objects are "passed by reference" in PHP but this is not true. A double indirection is responsible for this behaviour.
A recursive solution
function makeArray(array $arr, $initial)
{
if (! count($arr)) {
return $initial;
} else {
$key = array_shift($arr);
return [ $key => makeArray($arr, $initial) ];
}
}
$out = makeArray($arr, 1);
This solution iterates only once over the array and generates a hierarchy of arrays but recursivity is disastrous for large input arrays because it uses a lot of memory.