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";
}
此方法在关联数组中搜索特定键并返回与其关联的值。递归有一些问题。有线索吗?
也许对于旧版本的 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
}
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
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;
}
试试这个:
array_walk_recursive(
$arrayToFindKey,
function($value, $key, $matchingKey){
return (strcasecmp($key, $matchingKey) == 0)? true : false;
}
, 'matchingKeyValue'
);
我刚刚经历过类似的问题,这对我有用:
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 条件。有任何疑问或批评都非常欢迎,干杯!
我最近在处理 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);
如果键重复并且只返回第一个值,上面的最佳解决方案会错过这种情况,这里我得到数组中的所有值:(Demo)
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;
}
这是我的解决方案:
function find_value_by_key($key,$array) {
$data = array('key'=>$key,'ret'=>array());
array_walk_recursive($array,function($v,$k) use (&$data) {
if ($k==$data['key'])
$data['ret'][] = $v;
},$data);
return $data['ret'];
}
返回找到的值的数组,如果未找到键,则返回空数组。
如果您只需要返回它找到的第一个值,您可以使用:
function find_value_by_key($key,$array) {
$data = array('key'=>$key);
array_walk_recursive($array,function($v,$k) use (&$data) {
if (isset($data['ret']))
return;
if ($k==$data['key'])
$data['ret'] = $v;
},$data);
return $data['ret']?:false;
}
返回找到的第一个值。
如果未找到密钥,则返回
false
。
以下数组示例:
$数组=数组( 0 => 'A', 1 => 'B', 2 => 'C', 'foo' => '酒吧', 'mykey' => '哈哈', '测试' => 数组( '例子' => '哈哈', 'mykey' => '呼呼', ), '随机' => 数组( 大批( 'mykey' => '呵呵', 'notmykey' => 'topkek', ), 大批( 'mykey' => '呵呵', 'notmykey' => 'topkek', ), ), );
第一个函数将返回
["haha","hoho","hehe","huhu"]
,第二个函数将返回 "haha"