2012-12-27 15 views
7

mam następujące array (zwany $example_array poniżej):Dopasowane rekurencyjnej/wielowymiarową tablicę przeciwko innej tablicy

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

Chciałbym funkcji, które można uruchomić na tablicach tak i spojrzeć na mecz. Oto pytania, które chciałbym, aby móc wykonać:

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

Czy istnieje funkcja PHP wewnętrzne, które można używać albo będę musiał kodować coś sobie?

+0

Czy te trzy tablice, które powinny być dobrane w tablicy czy osobno? Czym jest logika dopasowywania? Czy element powinien być dopasowany, jeśli jeden z nich znajduje się w tablicy, którą należy przeszukać lub czy wszystkie powinny być dopasowane? – Leri

+0

Oddzielnie, każdy jest przykładem wyszukiwania, które można wykonać dla tablicy przykładowej. –

+0

wygląda jak praca z bazą danych –

Odpowiedz

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

Oto test script.

+0

Działa idealnie. Dziękuję Ci! –

+1

łatwy do odczytania i do punktu. +1 – didierc

0

Nie ma wbudowanego w to, co chcesz, iirc.

Oto (niesprawdzone) wersja z 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; 
} 

To dość zwięzły (można to zrobić lepiej z ?:), ale chyba nie bardzo czytelny. Lambdas to świetny dodatek do php!

Oto kolejna z możliwych rozwiązań, ale pozornie inneficient (ty wskaźnik powinien się upewnić):

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

Może to nie będzie działać, jeśli nie są używane wbudowane recursives.

1

Nadzieja ta funkcja pomaga:

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; 
} 
Powiązane problemy