递归搜索数组中的键
Posted
技术标签:
【中文标题】递归搜索数组中的键【英文标题】:Search for a key in an array, recursively 【发布时间】:2011-04-27 21:31:31 【问题描述】: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";
嘿,此方法在关联数组中搜索特定键并返回与其关联的值。递归有问题。有什么线索吗?
【问题讨论】:
你怎么不知道它在什么级别? 【参考方案1】:我最近在处理 Yii2 查询对象时遇到了同样的问题。
您的函数不起作用的原因是返回操作在这里不起作用。只需传递一个引用参数来存储值,然后做任何你想做的事情。
如您所见,这是一个简单的 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);
【讨论】:
【参考方案2】:我刚刚遇到了类似的问题,这对我有用:
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 条件。任何问题或批评都非常欢迎,干杯!
【讨论】:
【参考方案3】:也许它有点矫枉过正,但使用 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;
更新:此外,从 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
【讨论】:
谢谢。这救了我。如果您不需要对密钥进行严格比较,请记住将===
更改为==
。
注意,如果key在递归中出现多次,这里只会获取第一个的值。为了让他们都像这样修改它: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;
在 PHP 5.6 之后我会为此使用生成器,调用 yield
而不是 return
。
那会是@xPheRe【参考方案4】:
上面的最佳解决方案错过了如果键重复并且只返回第一个值的情况,这里我将所有值都放在一个数组中:
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】:xPheRe 提供的答案非常有帮助,但在我的实现中并没有完全解决问题。我们的数据结构中有多个嵌套的关联数组,并且任何给定的键都可能多次出现。
为了满足我们的目的,我需要实现一个在遍历整个结构时更新的持有者数组,而不是在第一次匹配时返回。真正的工作是由另一张海报提供的,但我想说声谢谢并分享我必须涵盖的最后一步。
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;
【讨论】:
【参考方案6】:试试这个:
array_walk_recursive(
$arrayToFindKey,
function($value, $key, $matchingKey)
return (strcasecmp($key, $matchingKey) == 0)? true : false;
, 'matchingKeyValue'
);
【讨论】:
array_walk_recursive 可能是 php 最没用的函数之一。它将跳过所有子数组,因此如果您的 $key 是另一个数组的键,您将找不到它【参考方案7】: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
【讨论】:
如果键值为'0'/零,则失败。然后使用下面的一个:fn 'recursiveFind'。以上是关于递归搜索数组中的键的主要内容,如果未能解决你的问题,请参考以下文章
PHP - 当给定子键名时,递归地将每个数组元素的键设置为子元素的值