【问题标题】:PHP Walk through multidimensional array while preserving keysPHP 在保留键的同时遍历多维数组
【发布时间】:2011-12-12 21:16:42
【问题描述】:

我有一个多维数组,我不知道它的深度。例如,该数组可能如下所示:

$array = array(
    1 => array(
        5 => array(
            3 => 'testvalue1'
        )
    ),
    2 => array(
        6 => 'testvalue2'
    ),
    3 => 'testvalue3',
    4 => 'testvalue4',
);

有了这个数组,我想创建一个目录。这意味着需要保留密钥,因为我将它们用作“章节编号”。例如,“testvalue1”在第 1.5.3 章中。
现在我想在保留所有键的同时遍历数组 - 不使用 array_walk_recursive 因为包含另一个数组的键被删除(正确吗?),考虑到速度,最好不要使用嵌套的 foreach 循环。
有什么建议我应该怎么做?提前致谢。

PS:对于我的脚本,键是字符串(“1”而不是 1)还是整数都没有关系,如果将字符串作为键将使 array_walk_recursive 保留它们。

【问题讨论】:

标签: php arrays loops multidimensional-array


【解决方案1】:

您可以在堆栈的帮助下迭代您的数组以构建您的目录。

$stack = &$array;
$separator = '.';
$toc = array();

while ($stack) {
    list($key, $value) = each($stack);
    unset($stack[$key]);
    if (is_array($value)) {
        $build = array($key => ''); # numbering without a title.
        foreach ($value as $subKey => $node)
            $build[$key . $separator . $subKey] = $node;
        $stack = $build + $stack;
        continue;
    }
    $toc[$key] = $key. ' ' . $value;
}

print_r($toc);

输出:

Array
(
    [1] => 1
    [1.5] => 1.5
    [1.5.3] => 1.5.3 testvalue1
    [2] => 2
    [2.6] => 2.6 testvalue2
    [3] => 3 testvalue3
    [4] => 4 testvalue4
)

如果需要,您也可以额外处理该级别,但您的问题并不清楚。

array_walk_recursive 不起作用,因为它不会为您提供父元素的键。另请参阅此相关问题:Transparently flatten an array,它有一个很好的答案,并且对更一般的情况也有帮助。

【讨论】:

  • 还有一个问题;当循环在数组中更深一层或多层时,它只会解析第一个键/值,然后返回到数组的第一层。例如,如果你有 $arr[1][0][1] 和 $arr[1][0][2],那么只有 $arr[1][0][1] 会被解析,然后循环会继续 $arr[2]... 等等。如何解决这个问题?
  • @Carlo:没看到你注意到这里。我编辑了代码没有问题。 array_shift 函数确实在您使用整数-数字键时重新编号了您的数组,这是 PHP 数组的一个特点。如果您不需要没有标题的数字,我会在添加它们的地方留下评论。
  • 完美。只有我希望 $toc 是字符串,所以我替换了 $toc = array();与 $toc = '';并替换了 $toc[$key] = $key. ' ' 。 $价值;与 $toc .= '['.$key. ']' 。 $价值。 ' - ';
【解决方案2】:
<?php
    $td = array(1=>array(5=>array(3=>'testvalue1',array(6=>'testvalue2'))),2=>array(6=>'testvalue2',array(6=>'testvalue2',array(6=>'testvalue2'),array(6=>'testvalue2',array(6=>'testvalue2')))),3=>'testvalue3',4=>'testvalue4');
    print_r($td);
    $toc = '';

    function TOC($arr,$ke='',$l=array()) {
            if (is_array($arr)) {
            if ($ke != '') array_push($l,$ke);
            foreach($arr as $k => $v)
                TOC($v,$k,$l);
        }
        else {
            array_push($l,$ke);
            $GLOBALS['toc'].=implode('.',$l)." = $arr\n";
        }
    }
    toc($td);
    echo "\n\n".$toc;
?>

http://codepad.org/4l4385MZ

【讨论】:

  • 难道没有其他方法不必使用许多嵌套循环吗?无论如何谢谢:)
  • 你必须嵌套循环来迭代多维数组。
  • @carlo Recursion 确实是解决这个问题最简单的方法。
  • @Korvin Szanto:你不必必须嵌套循环,你可以。见stackoverflow.com/questions/7854940/…
【解决方案3】:

试试这个:

<?php
$ar = array(
    1 => array(
        5 => array(
            3 => 'testvalue1',
            5 => 'test',
            6 => array(
                9 => 'testval 9'
            )
        ),
        8 => 'testvalue9'
    ),
    2 => array(
        6 => 'testvalue2',
        7 => 'testvalue8',
        2 => array(
            6 => 'testvalue2',
            7 => 'testvalue8'
        ),
    ),
    3 => 'testvalue3',
    4 => 'testvalue4'
);

function getNestedItems($input, $level = array()){
    $output = array();

    foreach($input as $key => $item){
        $level[] = $key;
        if(is_array($item)){
            $output = (array)$output + (array)getNestedItems($item, $level);
        } else {
            $output[(string)implode('.', $level)] = $item;
        }
        array_pop($level);
     }
     return $output;
}

var_dump(getNestedItems($ar));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2013-05-23
    • 2012-04-21
    • 2011-01-02
    • 2014-10-03
    • 2016-02-16
    • 2021-09-17
    相关资源
    最近更新 更多