2012-12-27 13 views
7

Ho il seguente array (chiamato $example_array sotto):Corrispondenza una matrice ricorsivo/multidimensionale contro un altro 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" 
      } 
     } 
} 

Vorrei una funzione che posso correre contro gli array come questo e per cercare una corrispondenza. Qui ci sono le ricerche che mi piacerebbe essere in grado di eseguire:

// 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')); 

C'è una funzione interna di PHP che posso usare o dovrò codice qualcosa di me?

+0

Sono quei tre matrici che dovrebbero essere abbinati in serie o separatamente? Qual è la logica della corrispondenza? L'elemento deve essere abbinato se uno di quelli è nella matrice che dovrebbe essere cercato o tutti dovrebbero essere abbinati? – Leri

+0

Separatamente, ognuno è un esempio di una ricerca che può essere eseguita sull'array di esempio. –

+0

sembra un lavoro di database –

risposta

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

Ecco lo test script.

+0

Funziona perfettamente. Grazie! –

+1

facile da leggere e al punto. +1 – didierc

0

Non c'è un builtin per fare quello che vuoi, iirc.

Ecco una versione (non testato) con 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; 
} 

E 'un po' conciso (si potrebbe fare meglio con ?:), ma forse non molto leggibile. Lambdas è una grande aggiunta a php!

Ecco un'altra soluzione possibile, ma apparentemente inneficient (si dovrebbe punto di riferimento per assicurarsi):

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

Forse non funziona se la funzione interna utilizzata non sono recursives.

1

Speranza questa funzione aiuta:

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