15

到目前为止,如果我必须遍历一个多维数组,我会为每个维度使用一个 foreach 循环。

例如二维

foreach($array as $key=>$value)
{
    foreach($value as $k2=>$v2)
    {
         echo
    }
}

不知道数组的深度怎么办?即深度是可变的。

我唯一能想到的就是编写整个循环堆栈并在下一个值不是数组时中断循环。这似乎有点傻。

有没有更好的办法?

4

5 回答 5

32

是的,您可以使用递归。这是一个输出数组中所有元素的示例:

function printAll($a) {
  if (!is_array($a)) {
    echo $a, ' ';
    return;
  }

  foreach($a as $v) {
    printAll($v);
  }
}

$array = array('hello',
               array('world',
                     '!',
                     array('whats'),
                     'up'),
               array('?'));
printAll($array);

在进行递归时,您应该始终记住的是,您需要一个不会更深入的基本案例。

我喜欢在继续该功能之前检查基本情况。这是一个常见的习语,但不是绝对必要的。如果您应该输出或进行递归调用,您也可以检查foreach循环,但我经常发现代码很难以这种方式维护。

当前输入和基本情况之间的“距离”称为变体,是一个整数。在每次递归调用中,变量都应该严格递减。上一个示例中的变体是the depth of $a. 如果您不考虑变体,则可能会导致无限递归,最终脚本将因堆栈溢出而死。在递归函数之前在注释中准确记录变体的内容并不少见。

于 2012-06-07T09:28:29.267 回答
5

您可以在不知道其深度的情况下为循环多维数组执行以下功能

// recursive function loop through the dimensional array
function loop($array){

    //loop each row of array
    foreach($array as $key => $value)
    {
         //if the value is array, it will do the recursive
         if(is_array($value) ) $array[$key] =  loop($array[$key]);

         if(!is_array($value)) 
         {
            // you can do your algorithm here
            // example: 
             $array[$key] = (string) $value; // cast value to string data type

         }
    }

    return $array;
}

通过使用上述函数,它将遍历每个多维数组,下面是您可以传递给循环函数的示例数组:

 //array sample to pass to loop() function
 $data = [
  'invoice' => [
      'bill_information' => [
          'price' => 200.00,
          'quantity' => 5
      ],
      'price_per_quantity' => 50.00
  ],
  'user_id' => 20
];

// then you can pass it like this :
$result = loop($data);
var_dump($result);

//it will convert all the value to string for this example purpose
于 2018-12-12T04:46:59.790 回答
1

您可以对这个问题使用递归:

这是一个例子

$array = array(1 => array(1 => "a", 2 => array(1 => "b", 2 => "c", 3 => array(1 => "final value"))));

//print_r($array);

printAllValues($array);

function printAllValues($arr) {
    if(!is_array($arr)) {
        echo '<br />' . $arr;
        return;
    }
    foreach($arr as $k => $v) {
        printAllValues($v);
    }
}

它将使用递归循环遍历数组

它会像这样打印

a
b
c
final value
于 2012-06-07T09:28:27.220 回答
0

根据前面的递归示例,这里有一个函数,它保存一个值所在的键的路径数组,以防你需要知道你是如何到达那里的:

function recurse($a,$keys=array()) 
    {
        if (!is_array($a)) 
            {
                echo implode("-", $keys)." => $a <br>";
                return;
            }
        foreach($a as $k=>$v) 
            {
                $newkeys = array_merge($keys,array($k));
                recurse($v,$newkeys);
            }
    }


recurse($array);
于 2019-01-01T19:25:30.630 回答
0

内部的简单函数array_walk_recursive用于显示嵌套级别以及键和值:

array_walk_recursive($array, function($v, $k) {
                                 static $l = 0;
                                 echo "Level " . $l++ . ": $k => $v\n";
                             });

另一个显示use参考以获得结果:

array_walk_recursive($array, function($v) use(&$result) {
                                 $result[] = $v;
                             });
于 2018-01-24T21:35:53.170 回答