15

これまでのところ、多次元配列をループする必要がある場合は、次元ごとにforeachループを使用します。

例:2次元の場合

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

array_walk_recursiveネストのレベルとキーと値を表示するための内部の単純な関数:

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

結果を得るための参照とともに表示されている別の1つuse

array_walk_recursive($array, function($v) use(&$result) {
                                 $result[] = $v;
                             });
于 2018-01-24T21:35:53.170 に答える
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 に答える