2013-10-31 128 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);