2012-12-27 54 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; 
}