Compare 2 arrays containing rows of data and displays the matched records

580 Views Asked by At

I am trying to figure out a way that I could match the 'userid' on both arrays. Then the ones that match, keep the rows in MongoDBResults.

$mysql = [
    ['id' => 1, 'userid' => 655342],
    ['id' => 3, 'userid' => 777777],
    ['id' => 6, 'userid' => 454777],
];

$mongo = [
    ['id' => 1, 'userid' => 655342, 'addr1' => '123 Test Ave', 'addr2' => 'MyCityState', 'zipcd' => '99955', 'items' => 888888],
    ['id' => 2, 'userid' => 989855, 'addr1' => '124 Test Ave', 'addr2' => 'MyCityState', 'zipcd' => '66955', 'items' => 887788],
    ['id' => 3, 'userid' => 777777, 'addr1' => '125 Test Ave', 'addr2' => 'MyCityState', 'zipcd' => '11955', 'items' => 886688],
    ['id' => 4, 'userid' => 666666, 'addr1' => '126 Test Ave', 'addr2' => 'MyCityState', 'zipcd' => '39954', 'items' => 885588],
];

Desired output:

array (
  0 => 
  array (
    'id' => 1,
    'userid' => 655342,
    'addr1' => '123 Test Ave',
    'addr2' => 'MyCityState',
    'zipcd' => '99955',
    'items' => 888888,
  ),
  2 => 
  array (
    'id' => 3,
    'userid' => 777777,
    'addr1' => '125 Test Ave',
    'addr2' => 'MyCityState',
    'zipcd' => '11955',
    'items' => 886688,
  ),
)

I tried:

$results = array_intersect($mysql, $mongo);

also

$result = array_diff($mysql, $mongo);
2

There are 2 best solutions below

0
AbraCadaver On BEST ANSWER

You can index on userid and then compute the intersection of the keys:

$results = array_intersect_key(array_column($MongoDBResults, null, 'userid'),
                               array_column($MySqlResults, null, 'userid'));
0
mickmackusa On

array_uintersect() is the most appropriate native function for this task. You are wanting to compare a specific column value among all rows from the two arrays. array_uintersect()'s callback parameter expects an integer value to be returned.

Returning a boolean from the callback (as demonstrated by @IliaYatsenko) will be converted to an integer, but this does not provide the possibility of a -1 value. Implementing a three-way comparison (done with the spaceship operator <=>) will allow the internal sorting to perform with optimal efficiency.

Code: (Demo)

var_export(
    array_uintersect(
        $mongo,
        $mysql,
        fn($a, $b) => $a['userid'] <=> $b['userid']
    )
);

Output:

array (
  0 => 
  array (
    'id' => 1,
    'userid' => 655342,
    'addr1' => '123 Test Ave',
    'addr2' => 'MyCityState',
    'zipcd' => '99955',
    'items' => 888888,
  ),
  2 => 
  array (
    'id' => 3,
    'userid' => 777777,
    'addr1' => '125 Test Ave',
    'addr2' => 'MyCityState',
    'zipcd' => '11955',
    'items' => 886688,
  ),
)

While @AbraCadaver's snippet works for this case, if the targeted columnar values were not unique in their respective arrays, it would destroy data due to key collisions. This is just a warning to future researchers.