Поиск ключа в массиве, рекурсивно - PullRequest
19 голосов
/ 20 октября 2010
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";
}

Эй, этот метод ищет определенный ключ в ассоциативном массиве и возвращает значение, связанное с ним.Есть некоторая проблема с рекурсией.Любая подсказка?

Ответы [ 5 ]

37 голосов
/ 20 октября 2010

Может быть, это излишне, но забавно использовать RecursiveIterators:)

ОБНОВЛЕНИЕ: Возможно, это было излишним со старыми версиями PHP, но с> = 5.6 (особенно с 7.0) Iбудет полностью использовать это без сомнения.

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
}
15 голосов
/ 20 октября 2010
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

4 голосов
/ 19 сентября 2014

Ответ, предоставленный 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;
}
2 голосов
/ 11 июля 2014

попробуйте это:

array_walk_recursive(
    $arrayToFindKey, 
    function($value, $key, $matchingKey){
        return (strcasecmp($key, $matchingKey) == 0)? true : false;
    }
    , 'matchingKeyValue'
);
0 голосов
/ 02 мая 2016

Лучшее решение выше пропускает случай, если ключ повторяется и возвращает только первое значение, здесь я получаю все значения в массиве:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...