2015-06-12 4 views
5

jestem zmaga się z odpowiednim logiki porównać następujące tablice:Porównywanie dwóch tablic dla dwóch wartości

$a = [ 
    "ip" => [ 
     "1.2.3.4", 
     "4.3.2.1", 
    ], 
    "domain" => [ 
     "example.com", 
     "another.domain", 
    ], 

]; 

$b = [ 
    [ 
     "id"=> 136589, 
     "metaname" => "ip", 
     "metavalue" => "1.2.3.4", 
    ], 
    [ 
     "id"=> 136590, 
     "metaname" => "domain", 
     "metavalue" => "example.com", 
    ], 
]; 

muszę pętli nad $a znaleźć klucz ('ip') Wartość ('1.2.3.4') kombinacje, które wykonują nie istnieje w $b. W tablicy $a, muszę zdobyć ip '4.3.2.1' i domenę 'another.domain'

Możliwe jest $b mieć odpowiadające wartości z różnych kluczy? Jest to dobry przykład adresów . Możliwe wartości metaname związane z IP to: 'ip', 'ip.dst' i 'ip.src'. Powrót do przykładowych danych - nawet jeśli dopasowanie 'ip', jeśli nazwa metaname nie jest zgodna, powinno zostać pominięte.

foreach ($a as $metaName => $metaValues) 
{ 
    foreach ($metaValues as $metaValue) 
    { 
     foreach ($b as $row) 
     { 
      if (in_array($metaName, $row) && in_array($metaValue, $row)) 
      { 
       # this pair exists, move on to next $metaName-$metaValue pair 
       break; 
      } 
      # this is where i am now, making small progress 
      # more trial and error going on 
     } 
    } 
} 

W moim przykładowym kodzie komentarz jest tam, gdzie potrzebuję pomocy. Próbowałem różnych iteracji pętli różnych kontroli i uchwycić odpowiednie dane bezskutecznie ...

  • in_array($metaValue, $row)
  • array_keys($row, $metaValue)

łączyć z różnymi if wypowiedzi i tak dalej, ale który wygrał nie pomóż.

W przypadku, gdy mój opis nie jest jasny, może posłużyć poniższa tabela.

+ A ---------------------+----+ B ------------------+ Comment ------------------------+ 
| ip, 1.2.3.4   | == | ip, 1.2.3.4   | Skip, no more checks   | 
+------------------------+----+---------------------+---------------------------------+ 
| ip, 4.3.2.1   | != | ip, 1.2.3.4   | Keep checking     | 
|      | != | domain, example.com | No more B to compare, I want A! | 
+------------------------+----+---------------------+---------------------------------+ 
| domain, example.com | != | ip, 1.2.3.4   | Keep checking     | 
|      | == | domain, example.com | Skip, no more checks   | 
+------------------------+----+---------------------+---------------------------------+ 
| domain, another.domain | != | ip, 1.2.3.4   | Keep checking     | 
|      | != | domain, example.com | No more B to compare, I want A! | 
+------------------------+----+---------------------+---------------------------------+ 

Odpowiedz

2

Z niewielkimi modyfikacjami i użyciem reference jesteś całkiem blisko. Ale należy być ostrożnym z pierwszej foreach, pierwszy argument jest $metaname, ale drugi nie jest jeszcze $metavalue, trzeba drugą foreach pętli nad nimi:

foreach ($a as $metaname => &$group) { // & is present to unset the original array 
    foreach ($group as $i => $metavalue) { // here you get the distinct metavalues 
     foreach ($b as $row) { 
      if (!($row['metaname'] === $metaname)) { 
       continue; 
      } 
      if ($row['metavalue'] === $metavalue) { 
       unset($group[$i]); 
      } 
     } 
    } 
} 

var_dump($a); 

var_dump() od $a potem

array(2) { 
    ["ip"]=> 
    array(1) { 
    [1]=> 
    string(7) "4.3.2.1" 
    } 
    ["domain"]=> 
    &array(1) { 
    [1]=> 
    string(14) "another.domain" 
    } 
} 

pierwszy foreach() by uzyskać dostęp do różnych wartościach $a macierzy, podczas gdy w rzeczywistości $metavalue tablica zawierający te metavalue.

+1

Aha! Nawet przy mojej częściowej pracy jest to trochę lepsze niż cały mój kod. Dziękuję bardzo. – user1801810