2010-10-20 74 views
16
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"; 
} 

嘿,這個方法在關聯數組中搜索一個特定的鍵並返回與它相關的值。遞歸有一些問題。任何線索?遞歸搜索數組中的鍵

+0

你怎麼會不知道它在什麼級別? – 2010-10-20 07:27:03

回答

12
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

+0

如果鍵值爲'0'/零,則失敗。然後使用一個波紋管:fn'recursiveFind'。 – phpJs 2013-12-19 01:25:44

31

也許是矯枉過正,但它很有趣,使用RecursiveIterators :)

UPDATE:也許對舊版本的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:此外,作爲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 
} 
+4

謝謝。這救了我。如果您不需要嚴格比較密鑰,請記住將'==='更改爲'=='。 – Batandwa 2013-08-01 08:20:40

+0

小心,如果鍵在遞歸中多次出現,它只會得到第一個鍵的值。爲了讓它們都像這樣修改它: 'function recursiveFind(array $ array,$ needle) { $ iterator = new RecursiveArrayIterator($ array); $ recursive = new RecursiveIteratorIterator( $ iterator, RecursiveIteratorIterator :: SELF_FIRST ); $ return = []; ($ key => $ value){ if $ key === $ needle) } } return $ return; } ' – 2016-05-02 20:28:30

+0

PHP 5.6之後我會使用一個生成器來調用'yield'而不是'return'。 – xPheRe 2016-05-02 21:00:41

1

試試這個:

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

由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; 
} 
+0

適合我的需求! – 2016-04-11 21:55:27

0

上面最好的解決辦法,如果錯過關鍵是反覆的情況下,只返回第一個值,在這裏我得到的所有的值的數組來代替:

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