从数组的键创建一个数组

时间:2015-05-19 14:51:09

标签: php arrays

让我假装我有这个:

$str = "/a/b/c/d/";
$arr = array_filter( explode("/", $str );

此时$arr包含4个元素。有没有办法可以在包含这4个元素的数组中创建路径,例如:

$result = [
    "a" => [
        "b" => [
            "c" => [
                "d" => [

                ]
            ]
        ]
    ]
]

...没有迭代$arr

我知道

$x["a"]["b"]["c"]["d"] = 1;

完全有效,即使$x未被声明为数组,它也会创建一个4级数组,所以我所要求的应该是可能的。

3 个答案:

答案 0 :(得分:1)

我不建议这样做,因为使用eval()时会产生安全隐患。但是,因为我在评论中说过没有迭代就无法完成,我觉得有必要将此作为答案发布(是的,我知道implode()在内部进行迭代)。

$str = "/a/b/c/d/";
$arr = array_filter( explode("/", $str ));

$keys = '["'.implode('"]["', $arr).'"]';
eval('$x'.$keys.' = 1;');

print_r($x);

更实际的方法请参阅How to write getter/setter to access multi-leveled array by dot separated key names?

答案 1 :(得分:1)

我曾写过一次函数,将此行为视为副作用。它不迭代,但使用递归。

请参阅:https://github.com/feeela/php-utils/blob/master/function.getArrayValueReference.php

你可以这样打电话:

<?php

$newArray = array();
$keys = 'a/b/c/d';

$referenceToD =& getArrayValueReference( $newArray, explode( '/', $keys ), true );

$referenceToD[0] = 'foo';
$referenceToD[1] = 'bar';

print_r( $newArray );

这会修改数组$newArray并创建所有级别。函数返回值是对最后一个键的引用(该示例中为“d”)。

...导致:

Array (
    [a] => Array (
        [b] => Array (
            [c] => Array (
                [d] => Array (
                    [0] => foo
                    [1] => bar
                )
            )
        )
    )
)

答案 2 :(得分:0)

如果没有迭代它,就无法使用$arr的所有值。

我想你不想写一个foreach循环但是使用一些PHP函数为你做迭代。

一个简单的解决方案,在数组上(场景后面)迭代两次

这是一个可能的解决方案:

$x = array_reduce(
    array_reverse($arr),
    function ($carry, $item) {
        return [$item => $carry];
    },
    1
);

它产生的结果与:

相同
$x = [];
$x['a']['b']['c']['d'] = 1;

不幸的是,它会重复$arr两次(array_reverse()array_reduce())。

另一种生成对象层次结构的解决方案

使用对象(stdClass)而不是数组生成所需嵌入的另一种方法:

$out = new stdClass;
array_reduce(
    $arr,
    function ($carry, $item) {
        $v = new stdClass;
        $carry->{$item} = $v;
        return $v;
    },
    $out
);

它使用$arr上的单个迭代工作,但它依赖于在PHP中处理对象的工作方式(这不适用于数组)。

PHP处理对象的方式使它们看起来像是通过引用传递的。这是一个常见的误解,即物体是通过参考传递的。在PHP但this is not true。双重间接负责此行为。

递归解决方案

function makeArray(array $arr, $initial)
{
    if (! count($arr)) {
        return $initial;
    } else {
        $key = array_shift($arr);
        return [ $key => makeArray($arr, $initial) ];
    }
}

$out = makeArray($arr, 1);

此解决方案仅在数组上迭代一次并生成数组层次结构,但递归性对于大型输入数组来说是灾难性的,因为它使用了大量内存。