Search for a key in an array, recursively

28,782

Solution 1

Maybe it's overkill, but it's funny to use 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.

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:

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
}

Solution 2

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.

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

Solution 3

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

Solution 4

try this:

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

Related videos on Youtube

The Onin
Author by

The Onin

I've been a hobbyist dev since 2002, turned pro in 2015. Founder at Read2Me.online CTO at Major Scale Analytics Freelancer at Upwork

Updated on July 09, 2022

Comments

  • The Onin
    The Onin almost 2 years
    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?

    • Ignacio Vazquez-Abrams
      Ignacio Vazquez-Abrams over 13 years
      How come you don't know what level it's at?
  • Batandwa
    Batandwa almost 11 years
    Thank you. This saved me. Remember to change the === to == if you don't need to do a strict comparison of the key.
  • phpJs
    phpJs over 10 years
    it fails if key value is '0'/zero. use one bellow then: fn 'recursiveFind'.
  • Aditya Mittal
    Aditya Mittal about 8 years
    Careful, if the key appears multiple times in the recursion, this only gets the value of the first one. To get them all modify it like this: 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; }
  • xPheRe
    xPheRe about 8 years
    After PHP 5.6 I'd use a generator for this, calling yield instead of return.
  • Marco Aurélio Deleu
    Marco Aurélio Deleu about 7 years
    how would that be @xPheRe
  • John
    John over 4 years
    array_walk_recursive is possibly one of the mose useless functions of php. It will skip all sub arrays, so if your $key is the key to another array you'll not find it