2012-12-27 103 views
7

我有以下陣列(稱爲$example_array下):匹配遞歸/多維數組對另一個陣列

array(3) { 
    ["id"]=> string(4) "123" 
    ["name"]=> 
     array(1) { 
     ["first"]=> string(3) "pete" 
     ["last"]=> string(3) "foo" 
     } 
    ["address"]=> 
     array(1) { 
     ["shipping"]=> 
      array(1) { 
       ["zip"]=> string(4) "1234" 
       ["country"]=> string(4) "USA" 
      } 
     } 
} 

我想,我可以運行對數組這樣,尋找一個匹配功能。下面是我想能夠執行搜索:

// These should return true: 
search($example_array, array('id' => '123')); 
search($example_array, array('name' => array('first' => 'pete')); 
search($example_array, array('address' => array('shipping' => array('country' => 'USA'))); 

// These don't have to return true: 
search($example_array, array('first' => 'pete')); 
search($example_array, array('country' => 'USA')); 

有沒有我可以使用PHP內部函數或我將不得不編寫自己的東西?

+0

是應該在陣列匹配或分開這三個陣列?匹配的邏輯是什麼?如果項目匹配,如果其中的一個數組應該被搜索或全部匹配? – Leri

+0

另外,每個都是可以針對示例數組執行搜索的示例。 –

+0

看起來像數據庫作業 –

回答

7
function search($array, $b) { 
    $ok = true; 
    foreach ($b as $key => $value) { 
     if (!isset($array[$key])) { $ok = false; break; } 
     if (!is_array($value)) 
      $ok = ($array[$key] == $value); 
     else 
      $ok = search($array[$key], $value); 
     if ($ok === false) break; 
    } 
    return $ok; 
} 

這是test script

+0

完美地工作。謝謝! –

+1

易於閱讀和重點。 +1 – didierc

0

有沒有內建可以做你想做的事情,iirc。

下面是一個(未經測試)版本array_walk

function search($data,$match) { 
    return array_walk($match, function($v,$k) use ($data) { 
     if (isset($data[$k])){ 
     if (is_array($v)) return search($data[$k],$v); 
     return ($v == $data[$k]); 
     }); 
     return false; 
} 

這有點簡潔(一個可以與?:做的更好),但也許不是很可讀。 Lambdas是一個偉大的除了PHP!

這裏的另一種可能的解決方案,但似乎inneficient(你應該基準,以確保):

function search($d,$m) { 
    return is_empty(array_diff_assoc(array_intersect_assoc($d,$m), $m)); 
} 

也許,如果使用內置的不recursives它不會工作。

1

希望這個功能有助於:

public function matchArray(&$arrayToSearch, $valueToMatch = array()){ 
    if(!is_array($valueToMatch)) 
     $valueToMatch = array($valueToMatch); 

    $exists = false; 
    $indexToMatch = array_keys($valueToMatch); 

    foreach($indexToMatch as $ind){ 
     if(array_key_exists($ind, $arrayToSearch)){ 
      $valToMatch = $valueToMatch[$ind]; 
      $value = $arrayToSearch[$ind]; 
      $valType = gettype($value); 
      $valToMatch = $valueToMatch[$ind]; 
      if($valType == gettype($valToMatch) || is_numeric($valToMatch)){ 
       if($valType == 'array'){ 
        $exists = $this->matchArray($value, $valToMatch); 
       } else if(($valType == 'string' || is_numeric($valToMatch)) && $valToMatch == $value) { 
        $exists = true; 
       } else { 
        $exists = false; 
        break; 
       } 
      } 
     } 
    } 

    return $exists; 
}