2015-06-12 39 views
5

Tôi đang phải vật lộn với logic thích hợp để so sánh các mảng sau:So sánh hai mảng cho hai giá trị

$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", 
    ], 
]; 

tôi cần phải lặp trên $a để tìm chìa khóa ('ip') giá trị ('1.2.3.4') kết hợp đó làm không tồn tại trong $b. Trong mảng $a, tôi cần chụp lại ip '4.3.2.1' và tên miền 'another.domain'

Có thể cho $b để có giá trị khớp với các khóa khác nhau?

Ví dụ điển hình là địa chỉ 'ip'. Giá trị metaname có liên quan đến IP có thể là 'ip', 'ip.dst''ip.src'. Quay lại dữ liệu mẫu - ngay cả khi các kết quả trùng khớp 'ip', nếu metaname không khớp với nó sẽ bị bỏ qua.

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

Trong mã mẫu, nhận xét là nơi tôi cần trợ giúp. Tôi đã cố gắng lặp lại hình kiểm tra khác nhau và vòng để nắm bắt dữ liệu thích hợp không có kết quả ...

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

kết hợp với nhiều if báo cáo và vân vân nhưng won mà không giúp được gì.

Trong trường hợp mô tả của tôi không rõ ràng, có thể bảng sau đây sẽ hữu ích.

+ 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! | 
+------------------------+----+---------------------+---------------------------------+ 

Trả lời

2

Chỉ với một sửa đổi nhỏ và việc sử dụng reference bạn rất gần. Nhưng hãy cẩn thận với foreach đầu tiên, số đầu tiên là một $metaname, nhưng thứ hai chưa phải là $metavalue, bạn cần một foreach thứ hai để lặp qua chúng:

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

một var_dump() của $a sau

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

các foreach đầu tiên() sẽ truy cập vào các giá trị riêng biệt của $a mảng trong khi $metavalue là trong thực tế mảng chứa những metavalues.

+1

Aha! Ngay cả với tôi chỉ một phần làm việc này là khá tốt hơn một chút so với mã hoàn chỉnh tôi đã có. Cảm ơn rất nhiều. – user1801810

Các vấn đề liên quan