递归搜索多维数组时获取第一个匹配键的值

发布于 2024-09-28 09:47:24 字数 412 浏览 0 评论 0原文

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";
}

此方法在关联数组中搜索特定键并返回与其关联的值。递归有一些问题。有什么线索吗?

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";
}

This method searches for a specific key in an associative array and returns the value associated with it. There's some problem with the recursion. Any clue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

兔姬 2024-10-05 09:47:24

也许它对于旧版本的 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
}

Maybe it was overkill with old versions of PHP, but with >=5.6 (specially with 7.0) I would totally use this without doubt.

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;
        }
    }
}

Also, as of PHP 5.6, with generators you can easily iterate over all elements which pass the filter, not only the first one:

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
}
一影成城 2024-10-05 09:47:24
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

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;
} 

You need to stop the recursive deep search, by return false and then check it in the function.

You can find more examples of functions (like using RecursiveArrayIterator and more) in this link:
http://php.net/manual/en/function.array-search.php

嘿看小鸭子会跑 2024-10-05 09:47:24

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;
}

The answer provided by xPheRe was extremely helpful, but didn't quite solve the problem in my implementation. There are multiple nested associative arrays in our data structure, and there may be multiple occurrences of any given key.

In order to suit our purposes, I needed to implement a holder array that was updated while traversing the entire structure, instead of returning on the first match. The real work was provided by another poster, but I wanted to say thanks and share the final step that I had to cover.

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;
}
野味少女 2024-10-05 09:47:24

我刚刚经历过类似的问题,这对我有用:

    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 条件。有任何问题或批评都欢迎,干杯!

I just been through a similar issue and here's what worked for me:

    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;
     }
   }

This is going to return an array containing the value of all the matching keys it found in the multidimensional array. I tested this with arrays dinamically generated by an e-mail API. In the case of multiple matches, you just need to create a simple foreach loop to sort the array however you want.

I noticed the main mistake I was making was using if-ifelse conditions when I should be using if-if conditions. Any questions or criticism are very welcome, cheers!

羁绊已千年 2024-10-05 09:47:24

我最近在处理 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);

I recently came across the same issue, when dealing with Yii2 query object.

The reason your function didn't work is that the return action doesn't work here. Just pass a reference parameter to store the value, and do whatever you want afterwards.

As you can see, this is a simple PHP function doesn't rely on any library. So I think its worth to mention with all the answer listed above.

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);

素衣风尘叹 2024-10-05 09:47:24

如果键重复并且仅返回第一个值,上面的最佳解决方案会错过这种情况,这里我获取数组中的所有值: (演示)

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;
}

The best solution above misses the case if the key is repeated and only returns the first value, here I get all the values in an array instead: (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;
}
淡淡の花香 2024-10-05 09:47:24

这是我的解决方案:

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 => '一个',
1 => 'B',
2=> 'C',
'foo'=> '酒吧',
'mykey'=> '哈哈',
'测试' =>大批(
'示例' => '哈哈',
'mykey'=> '嗬嗬',
),
'随机' =>大批(
大批(
'mykey'=> '呵呵',
'notmykey'=> '托普克',
),
大批(
'mykey'=> '呼呼',
'notmykey'=> '托普克',
),
),);

第一个函数将返回 ["haha","hoho","hehe","huhu"],第二个函数将返回 "haha"

Here's my solution:

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'];
}

Returns an array of the value(s) found, if the key isn't found then an empty array is returned.

If you only need to return the first value it finds you can use:

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;
}

Returns the first value found.

If the key isn't found then false is returned.

Example with the following array:

$array = array(
0 => 'A',
1 => 'B',
2 => 'C',
'foo' => 'bar',
'mykey' => 'haha',
'test' => array(
'example' => 'lol',
'mykey' => 'hoho',
),
'random' => array(
array(
'mykey' => 'hehe',
'notmykey' => 'topkek',
),
array(
'mykey' => 'huhu',
'notmykey' => 'topkek',
),
), );

First function would return ["haha","hoho","hehe","huhu"], second one would return "haha"

吹泡泡o 2024-10-05 09:47:24

试试这个:

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

try this:

array_walk_recursive(
    $arrayToFindKey, 
    function($value, $key, $matchingKey){
        return (strcasecmp($key, $matchingKey) == 0)? true : false;
    }
    , 'matchingKeyValue'
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文