递归地搜索数组中的键

时间:2010-10-20 07:26:07

标签: php arrays search recursion

private function find($needle, $haystack) {
    foreach ($haystack as $name => $file) {
        if ($needle == $name) {
            return $file;
        } else if(is_array($file)) { //is folder
            return $this->find($needle, $file); //file is the new haystack
        }               
    }

    return "did not find";
}

嘿,此方法在关联数组中搜索特定键,并返回与之关联的值。递归有一些问题。任何线索?

7 个答案:

答案 0 :(得分:36)

也许它有点矫枉过正,但使用RecursiveIterators很有趣:)

更新:也许这对旧版本的PHP来说太过分了,但是使用> = 5.6(特别是7.0)我会毫无疑问地完全使用它。

function recursiveFind(array $haystack, $needle)
{
    $iterator  = new RecursiveArrayIterator($haystack);
    $recursive = new RecursiveIteratorIterator(
        $iterator,
        RecursiveIteratorIterator::SELF_FIRST
    );
    foreach ($recursive as $key => $value) {
        if ($key === $needle) {
            return $value;
        }
    }
}

UPDATE:此外,从PHP 5.6起,使用生成器,您可以轻松地遍历通过过滤器的所有元素,而不仅仅是第一个:

function recursiveFind(array $haystack, $needle)
{
    $iterator  = new RecursiveArrayIterator($haystack);
    $recursive = new RecursiveIteratorIterator(
        $iterator,
        RecursiveIteratorIterator::SELF_FIRST
    );
    foreach ($recursive as $key => $value) {
        if ($key === $needle) {
            yield $value;
        }
    }
}

// Usage
foreach (recursiveFind($haystack, $needle) as $value) {
    // Use `$value` here
}

答案 1 :(得分:15)

function array_search_key( $needle_key, $array ) {
  foreach($array AS $key=>$value){
    if($key == $needle_key) return $value;
    if(is_array($value)){
      if( ($result = array_search_key($needle_key,$value)) !== false)
        return $result;
    }
  }
  return false;
} 

这会有效!

你需要停止递归深度搜索,返回false然后在函数中检查它。

您可以在此链接中找到更多函数示例(例如使用RecursiveArrayIterator等): http://php.net/manual/en/function.array-search.php

答案 2 :(得分:4)

xPheRe提供的答案非常有用,但在我的实现中并没有完全解决问题。我们的数据结构中有多个嵌套的关联数组,任何给定的键可能会多次出现。

为了满足我们的目的,我需要实现一个在遍历整个结构时更新的holder数组,而不是在第一个匹配时返回。真正的工作是由另一张海报提供的,但我想表示感谢并分享我必须承担的最后一步。

public function recursiveFind(array $array, $needle)
{
    $iterator  = new RecursiveArrayIterator($array);
    $recursive = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
    $aHitList = array();
    foreach ($recursive as $key => $value) {
        if ($key === $needle) {
            array_push($aHitList, $value);
        }
    }
    return $aHitList;
}

答案 3 :(得分:2)

试试这个:

array_walk_recursive(
    $arrayToFindKey, 
    function($value, $key, $matchingKey){
        return (strcasecmp($key, $matchingKey) == 0)? true : false;
    }
    , 'matchingKeyValue'
);

答案 4 :(得分:0)

如果重复键并且只返回第一个值,那么上面的最佳解决方案会错过这种情况,这里我得到了数组中的所有值:

function recursiveFind(array $array, $needle) {
  $iterator = new RecursiveArrayIterator($array);
  $recursive = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
  $return = [];
  foreach ($recursive as $key => $value) {
    if ($key === $needle) {
      $return[] = $value;
    }
  } 
  return $return;
}

答案 5 :(得分:0)

我最近在处理Yii2查询对象时遇到了同样的问题。

您的函数不起作用的原因是return操作在这里不起作用。只需传递一个引用参数来存储该值,然后再执行任何操作即可。

如您所见,这是一个简单的PHP函数,不依赖任何库。因此,我认为值得一提的是上面列出的所有答案。

function array_search_by_key_recursive($needle, array $haystack, &$return)
{
   foreach ($haystack as $k => $v) {
      if (is_array($v)) {
        array_search_by_key_recursive($needle, $v, $return);
      } else {
        if($k === $needle){
           $return = $v;
        }
      }
   }
}

array_search_by_key_recursive($needle, array $haystack, $return);

print_r($return);

答案 6 :(得分:0)

我刚遇到类似的问题,这对我有用:

    function searchArrayByKey($haystack, $needle, $i = 0) {
     $result = array();
     foreach($haystack as $key => $value) {
       if (is_array($value)) {
         $nextKey = searchArrayByKey($value, $needle);
         if ($nextKey) {
           return $nextKey;
         }
       }
       if (is_array($value) && array_key_exists($needle, $value)) {
         $result[$i++] = $value[$needle];
       }
     }
     if (empty($result)) {
       return false;
     } else {
       return $result;
     }
   }

这将返回一个数组,其中包含它在多维数组中找到的所有匹配键的值。我用电子邮件API动态生成的数组进行了测试。如果有多个匹配项,则只需创建一个简单的foreach循环即可对数组进行任意排序。

当我应该使用if-if条件时,我注意到我犯的主要错误是使用if-ifelse条件。任何问题或批评都非常欢迎,欢呼!