递归地搜索数组中的键

时间:2021-11-04 21:19:53
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";
}

Hey, 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?

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

5 个解决方案

#1


32  

Maybe it's overkill, but it's funny to use RecursiveIterators :)

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

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

更新:也许它对旧版本的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: Also, as of PHP 5.6, with generators you can easily iterate over all elements which pass the filter, not only the first one:

更新:此外,从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
}

#2


14  

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

this will work !

这会奏效!

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

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

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

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

#3


4  

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.

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

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.

为了满足我们的目的,我需要实现一个在遍历整个结构时更新的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;
}

#4


1  

try this:

尝试这个:

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

#5


0  

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:

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

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

#1


32  

Maybe it's overkill, but it's funny to use RecursiveIterators :)

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

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

更新:也许它对旧版本的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: Also, as of PHP 5.6, with generators you can easily iterate over all elements which pass the filter, not only the first one:

更新:此外,从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
}

#2


14  

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

this will work !

这会奏效!

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

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

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

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

#3


4  

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.

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

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.

为了满足我们的目的,我需要实现一个在遍历整个结构时更新的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;
}

#4


1  

try this:

尝试这个:

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

#5


0  

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:

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

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