2013-10-31 127 views
8

我想寫一個遞歸數組迭代器函數,其中函數將返回由'$ needle'指定的所有集合的結果集。其中$針=鍵PHP - 遞歸多維數組迭代器

這裏是我的功能:

function recursive($needle, $array, $holder = array()) { 
    foreach ($array as $key => $value) { 
     if (gettype($value) == 'array') { 
      if ($key != $needle) { 
       recursive($needle, $value); 
      } elseif ($key == $needle) { 
       if (!empty($value)) { 
        array_push($holder, $value); 
       } 
      } 
     } 
    } 
    return $holder; 
} 

但我不會讓所有的結果返回,而是弄了幾個空的結果,如果我不指定!empty($value),雖然輸入數組沒有任何空集。我究竟做錯了什麼?

+3

array_walk_recursive或array_search和很多內置函數有沒有 –

+0

@ArunKillu那是不相關的。我寫的函數有什麼問題? – dudemanbearpig

+4

我們需要一個觸發錯誤的示例數組和函數參數。否則,不能複製問題。 – Sven

回答

16

你不需要重新發明輪子,因爲PHP有​​標準Recursive Iterator API:

//$array is your multi-dimensional array 
$result = []; 
$search = 'foo'; 
$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(
     $array, 
     RecursiveArrayIterator::CHILD_ARRAYS_ONLY 
    ) 
); 

foreach($iterator as $key=>$value) 
{ 
    if($search==$key && $value!=='') 
    { 
     $result[] = $value; 
    } 
} 

- 音符,即,因爲你通過關鍵尋找價值- 在通常情況下$value將舉行整個小節。

如果你想這樣做,在你自己的遞歸函數,這裏有一個:

function recursive($needle, $array, $holder = []) 
{ 
    $holder = []; 
    foreach($array as $key=>$value) 
    { 
     if($key===$needle && $value!=='') 
     { 
      $holder = array_merge($holder, [$value]); 
     } 
     if(is_array($value)) 
     { 
      $holder = array_merge($holder, recursive($needle, $value, $holder)); 
     } 
    } 
    return $holder; 
} 
+0

其實這是不正確的。有一個問題,RecursiveArrayIterator實際上是一個'RecursiveArrayAndObjectIterator',這不是OP正在尋找的或者。只是說。 – hakre

+0

@hakre hm。不知道我得到了。在哪裏反對迭代器? –

+0

沒有意見反對迭代器,也許(也許!)錯誤的迭代器。 – hakre

0

您建設的細小的改動:

$holder = recursive($needle, $value, $holder);

好哦?

+0

只將整個數組傳遞給函數,最終只是隨機地將整個數組吐出,因爲它發現$ needle ... – dudemanbearpig

+2

好的,請更具體地說明您希望用您的函數實現的功能。返回匹配你的鍵的數組元素?或者是其他東西...? – matthias

+1

順便說一下:它不會傳遞「整個數組」,它傳遞的$持有者被初始化爲空數組,然後在(key == $ needle)匹配時發生修改,並將這些後續元素推送給它。正如你所說的「一套結果集」...... – matthias

1

更細粒度的控制也許是可能的(TM)遞歸陣列經由RecursiveIterator接口遍歷和一些鍵過濾器和陣列轉換功能:

$needle = '0'; 
$array = [[1]]; 

$it = new KeyFilter(
    new RecursiveIteratorIterator(
     new MyRecursiveArrayIterator($array) 
     , RecursiveIteratorIterator::SELF_FIRST 
    ) 
    , $needle 
); 

$result = iterator_to_array($it, FALSE); 
var_dump($result); 

提供的示例性結果爲:

array(2) { 
    [0] => 
    array(1) { 
    [0] => 
    int(1) 
    } 
    [1] => 
    int(1) 
} 

完整代碼示例(Demo):

<?php 
/** 
* @link http://stackoverflow.com/q/19709410/367456 
*/ 

Class MyRecursiveArrayIterator extends ArrayIterator implements RecursiveIterator 
{ 
    public function hasChildren() 
    { 
     $current = $this->current(); 
     return is_array($current) && count($current); 
    } 

    public function getChildren() 
    { 
     return new self($this->current()); 
    } 
} 

class KeyFilter extends RegexIterator 
{ 
    public function __construct(Iterator $iterator, $key) 
    { 
     parent::__construct(
      $iterator, '/' . preg_quote($key) . '/', NULL, RegexIterator::USE_KEY 
     ); 
    } 
} 

$needle = '0'; 
$array = [[1]]; 

$it = new KeyFilter(
    new RecursiveIteratorIterator(
     new MyRecursiveArrayIterator($array) 
     , RecursiveIteratorIterator::SELF_FIRST 
    ) 
    , $needle 
); 

$result = iterator_to_array($it, FALSE); 
var_dump($result);