[ "1.2.3.4", "4.3....">

Comparing two arrays for two values

I am struggling with the appropriate logic to compare the following arrays:

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

I need to iterate over $a to find the key combinations ( 'ip' ) ( '1.2.3.4' ) that are not in $b . In the array $a I need to write ip '4.3.2.1' and the domain 'another.domain'

Can $b have matching values ​​with different keys?

A good example is the 'ip' address. Possible values ​​for a metasubstituted IP connection are: 'ip' , 'ip.dst' and 'ip.src' . Let's go back to the data samples, even if the match is 'ip' , if the methane name does not match, it should be skipped.

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

In my code example, a comment is where I need help. I tried various iterations of various checks and loops to capture the corresponding data to no avail ...

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

combined with various if , etc., but that will not help.

In case my description may not be clear, perhaps the following table will help.

 + 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! | +------------------------+----+---------------------+---------------------------------+ 
+5
source share
1 answer

With a little modification and using reference you are pretty close. But be careful with the first foreach, the first argument is $metaname , but the second is not yet $metavalue , you will need a second foreach to $metavalue over them:

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

a var_dump() of $a after

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

The first foreach () will access the different values ​​of the $a arrays, while $metavalue is an array containing these meta-conclusions.

+2
source

All Articles