2010-11-30 13 views
6

未知数/無制限の深さにネストされた多次元配列を持っています。 私はすべての要素をループすることができるようにしたいと思います。 私は深さを知らないので、foreach(){foreach(){foreach(){}}}を使用したくありません。無限深度にネストされた多次元配列

私は最終的に "xyz"と呼ばれるすべてのネストされた配列を探しています。誰にも何か提案がありますか?

答えて

1

、私は答えを見つけた:

function findXyz($array){ 
    foreach($array as $foo=>$bar){ 
     if (is_array($bar)){ 
     if ($bar["xyz"]){ 
      echo "<br />The array of xyz has now been found"; 
      print_r($bar['xyz']); 
     }else{ 
      findXyz($bar); 
     } 
     } 
    } 
} 
findXyz($myarray); 

これが私の元ごとに、すべてのネストされた配列をループし、XYZのサブアレイを有する任意の要素を探します要求。 array_walk_arrayとRecursiveIteratorIteratorはこれを実現できませんでした。

3

再帰。

1つの配列をウォークする関数を記述します。配列でもある各要素に対して、自身を呼び出します。それ以外の場合は、ターゲット文字列を見つけると、それを返します。

+0

この再帰関数はforまたはforeachを使用する必要があります – Thariama

+0

はい、ただし一度だけです。ハードコードされたネストレベルではありません。 – tdammers

0

これにはarray_walk_recursiveを使用することを考えましたか?

別(遅い)アプローチは、検索を実行する前flatten the array最初になり、すなわち:

$myarray = array('a','b',array(array(array('x'),'y','z')),array(array('p'))); 

function array_flatten($array,$return) 
{ 
    for($x = 0; $x <= count($array); $x++) 
    { 
     if(is_array($array[$x])) 
     { 
      $return = array_flatten($array[$x],$return); 
     } 
     else 
     { 
      if($array[$x]) 
      { 
       $return[] = $array[$x]; 
      } 
     } 
    } 
    return $return; 
} 

$res = array_flatten($myarray,array()); 

あるいは、再帰的な検索のために、例えばhereを参照してください。

function arrayRecursiveSearch($needle, $haystack, $path=""){ 
    if(!is_array($haystack)){ 
    die("second argument is not array"); 
    } 

    global $matches; 

    foreach($haystack as $key=>$value) 
    { 
    if(preg_match("/$needle/i", $key)){ 
     $matches[] = array($path . "$key/", "KEY: $key"); 
    } 

    if(is_array($value)){ 
     $path .= "$key/"; 
     arrayRecursiveSearch($needle, $value, $path); 
     unset($path); 
    }else{ 
     if(preg_match("/$needle/i", $value)){ 
     $matches[] = array($path . "$key/", "VALUE: $value"); 
     } 
    } 
    } 

    return $matches; 
} 

$arr = array("Asia"=>array('rambutan','duku'), 
       "Australia"=>array('pear','kiwi'), 
       "Arab"=>array('kurma')); 

print_r(arrayRecursiveSearch("ra",$arr)); 
+0

array_walk_recursiveは、PHP.netのドキュメンテーションのこの小さな節を除いてすばらしく動作します。「キー 'sweet'が表示されないことがあります。配列を保持するキーは関数に渡されません」 – stevenmc

3

がありますa 広大な不明と無制限の違い。ただし、複数のネストされたforeachループを使用する代わりにSPL Iteratorsを使用することができます。

例:

$array_obj = new RecursiveIteratorIterator(new RecursiveArrayIterator($array)); 
foreach($array_obj as $key => $value) { 
    echo $value; 
} 
+0

配列に別の配列が含まれていると、インデックスが渡されないという点で、array_walk_arrayと同じ問題が発生します。 – stevenmc

1

RecursiveIteratorIteratorインターフェースに見てください。上記のコメントを使用して

$interface = new RecursiveIteratorIterator(new RecursiveArrayIterator($your_array)); 
foreach($interface as $k=>$v) { /* your function*/ } 
10

私は最終的に "xyz"と呼ばれるすべてのネストされた配列を探しています。誰にも何か提案がありますか?

確かに。いくつかのイテレータを使用するための提案を踏まえ、あなたが行うことができます:

$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator($array), 
    RecursiveIteratorIterator::SELF_FIRST 
); 
foreach ($iterator as $key => $item) { 
    if (is_array($item) && $key === 'xyz') { 
     echo "Found xyz: "; 
     var_dump($item); 
    } 
} 

他の回答との間の重要な違いこのRecursiveIteratorIterator::SELF_FIRSTフラグは非リーフ(すなわち親)のアイテムを作るために使用されているということで(つまり、配列)が表示されます。

ループ内の配列をチェックするのではなく、配列イテレータの周りにParentIteratorを使用して、後者をちょっとしたものにすることもできます。