【问题标题】:PHP - How to turn a single array to multi-dimensional array?PHP - 如何将单个数组转换为多维数组?
【发布时间】:2017-07-22 12:53:48
【问题描述】:

我有一个像这样的数组:

array (
    '0' => 1,
    '1' => 3,
    '2' => 4
)

我想把它变成一个多维数组,比如:

array (
    '1' =>
        array (
            '3' => '4'
        ),
)

另一个数组:

array (
    '0' => 'a',
    '1' => 'b',
    '2' => 'c',
    '3' => 'd'
)

到:

array (
    'a' =>
        array (
            'b' =>
                array (
                    'c' => 'd'
                ),
        ),
),

我怎样才能做到这一点?

注意
该数组是动态的,并不总是包含 3 或 4 个元素。

【问题讨论】:

  • 最后一个必须是真正的值,它之前的一切都成为索引。抱歉我的英语不好,我更新了我的问题。
  • 你的例子没有逻辑
  • 这听起来像是一个编程挑战——可能适合在 codegolf 或 codereview.stackexchange.com 上
  • @Wordica 确实如此。但是需要一些时间来理解。他希望每个值都成为一个新键,其中一个数组作为嵌套在前一个数组中的值,并将最后一个值设置为最后一个嵌套数组的值。挺难理解的,但是有道理

标签: php arrays multidimensional-array logic


【解决方案1】:

有多种方法可以实现这一点:

简单的for循环

首先,使用array_pop() pop(即存储和删除)数组中的最后一个值。然后从数组的末尾开始迭代,依次创建一个包含值的数组(通过array_values()):

function transformArray($input) {
    $accumulator = array_pop($input);
    $values = array_values($input);
    for($i = count($input)-1; $i > -1; $i--) {
        $accumulator = array($values[$i] => $accumulator);    
    }
    return $accumulator;
}

this playground example中看到它的演示

foreach 循环

使用前面示例中的代码,for 循环可以通过 array_reverse() 替换为 foreach 循环。这样我们就不必担心何时开始和停止索引值、索引到数组等。

function transformArray($input) {
    $accumulator = array_pop($input);
    $values = array_reverse(array_values($input));
    foreach($values as $value) {
        $accumulator = array($value => $accumulator);    
    }
    return $accumulator;
}

请参阅this playground example 中的演示。

函数式方法:array_reduce()

Array_reduce() 可用于简化迭代。 array_reduce() 的第一个参数是输入数组,第二个是回调函数,第三个是初始值。回调函数的参数是 accumulator 值(来自先前的迭代)和当前数组索引处的数组元素)。初始值用作第一次迭代的累加器值,因此我们可以传递从数组末尾弹出的值。

function transformArray($input) {
    $accumulator = array_pop($input);
    $values = array_reverse(array_values($input));
    return array_reduce($values, function($accumulator, $element) {
        return array($element => $accumulator);
    }, $accumulator);
}

请参阅this playground example 中的演示。

递归方法

也许最简单的技术是使用递归函数,使用array_shift()从数组中取出第一个元素并返回一个以该元素为键的数组,值是调用同一函数的返回值,除非只有一件物品,在这种情况下,一件物品被退回。

function transformArray($input) {
    if (count($input) == 1) {
        return $input[0];
    }
    return array(array_shift($input) => transformArray($input));
}

请参阅this playground example 中的演示。

【讨论】:

  • 非常感谢。这正是我所需要的。
【解决方案2】:

如果它总是有 3 个元素:

  $temp = array (
            '0' => 1,
            '1' => 3,
            '2' => 4
        ); 

  $result = array();

  $result[$temp['0']] = array($temp['1'] => $temp['2']);

【讨论】:

  • 对不起,我已经编辑了我的问题,元素是动态的
  • 所以你想继续在新数组中推送元素?你能举出更多的例子吗?
【解决方案3】:

虽然我认为有更好的策略,但可以使用eval() 来达到此目的:

<?php

/* Example array */
$arr1 = array(
    '0' => 'a',
    '1' => 'b',
    '2' => 'c',
    '3' => 'd'
);

$array_string = '';

/* Build array string */
for($i = 0; $i < count($arr1); $i++){
    if($i < (count($arr1) - 1)){
        $array_string .= 'array ( \''. $arr1[$i] .'\' => ';
    } else {
        $array_string .= ' \''. $arr1[$i] .'\'';
    }
}

/* Close array string */
for($y = 0; $y < count($arr1); $y++){
    if($y < (count($arr1) - 2)){
        $array_string .= ' ), ';
    } else {
        $array_string .= ' )';
        break;
    }
}

/* Evaluate array string as PHP code and put it in $result */
$result = eval("return $array_string;");

/* Print the result */
echo '<pre>';
print_r($result);
echo '</pre>';

?>

结果:

Array
(
    [a] => Array
        (
            [b] => Array
                (
                    [c] => d
                )

        )

)

但正如我所说,请记住这句话:

如果 eval() 是答案,那么您几乎肯定会问错问题。 -- Rasmus Lerdorf,PHP 的 BDFL

问问自己为什么需要这个。是否有其他策略可满足您的需求?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 2011-10-10
    相关资源
    最近更新 更多