递归创建多维数组

时间:2014-07-01 10:11:14

标签: php arrays recursion multidimensional-array eval

原始数组如下所示:

$array = array(
    array(
        'key' => 'key1',
        'val' => 'val1'
    ),
    array(
        'key' => 'key2:subkey1',
        'val' => 'val2'
    ),
    array(
        'key' => 'key3:subkey2',
        'val' => 'val3'
    ),
    array(
        'key' => 'key3:subkey3:subsubkey1',
        'val' => 'val4'
    ),
    array(
        'key' => 'key3:subkey3:subsubkey2',
        'val' => 'val5'
    ),
    array(
        'key' => 'key3:subkey3:subsubkey3',
        'val' => 'val6'
    )
);

我想生成一个基于原始数组的新数组:

$result = array(
    'key1' => 'val1',
    'key2' => array(
        'subkey1' => 'val2'
    ),
    'key3' => array(
        'subkey2' => 'val3',
        'subkey3' => array(
            'subsubkey1' => 'val4',
            'subsubkey2' => 'val5',
            'subsubkey3' => 'val6'            
        )
    )
);

该算法应该能够处理任何深度的参考数组。 到目前为止我尝试过的是有效的,但由于各种原因我使用eval并不满意:

function convert($array) {
    $out = array();
    foreach ($array as $data) {
        $key = $data['key'];
        $pos = strpos($key, ':');
        if ($pos === false) {
            $out[$key] = $data['val'];
        } else {
            $split = explode(":", $key);
            eval("\$out['" . implode("']['", $split) . "'] = '" . $data['val'] . "';");
        }
    }
    return $out;
}

有没有办法解决这个问题而不诉诸eval,即直接设置$outval来自用户输入,因此在这种情况下使用eval显然非常不安全。

感谢您的建议。

2 个答案:

答案 0 :(得分:0)

试试这个简洁的代码:

$array = array(
               array(
                     'key' => 'key1',
                     'val' => 'val1'
                    ),
               array(
                     'key' => 'key2:subkey1',
                     'val' => 'val2'
                    ),
               array(
                     'key' => 'key3:subkey2',
                     'val' => 'val3'
                    ),
               array(
                     'key' => 'key3:subkey3:subsubkey1',
                     'val' => 'val4'
                    ),
               array(
                     'key' => 'key3:subkey3:subsubkey2',
                     'val' => 'val5'
                    ),
               array(
                     'key' => 'key3:subkey3:subsubkey3',
                     'val' => 'val6'
                    )
              );

$new_array = array();

foreach($array as $element) {
    $temp = &$new_array;

    foreach(explode(':', $element['key']) as $key) {
        $temp = &$temp[$key];
    }

    $temp = $element['val'];
}

unset($temp);

var_dump($new_array);

答案 1 :(得分:0)

function convert($array) {
    $out = array();
    foreach ($array as $data) {
        $key = $data['key'];
        $value = $data['val'];
        $helper = &$out;
        foreach (explode(':', $key) as $i) {
            $helper = &$helper[$i];
        }
        $helper = $value;
    }

    return $out;
}

我花了一段时间才弄明白该怎么做。参考文献可能是实现它的最佳方式。

$helper - 变量是我们想要在完成后返回的$out数组的临时引用。它将每个键以冒号分隔为分隔符,并遍历每个单独的键。在每次迭代中,我们都将帮助器引用更改为下一个键。

一个例子:

$out = array();

explode(':', $key) => array('key3', 'subkey3', 'subsubkey1');
$helper = &$out;

// foreach loop starts
$helper = $helper['key3']; // Iteration 1
$helper = $helper['key3']['subkey3']; // Iteration 2
$helper = $helper['key3']['subkey3']['subsubkey1']; // Iteration 3

我希望你能理解它是如何运作的。