Search code examples
phparraysmultidimensional-arrayfilteringarray-intersect

Find intersecting rows between two 2d arrays comparing differently keyed columns


I have two arrays,

The $first has 5000 arrays inside it and looks like:

array(
  array('number' => 1),
  array('number' => 2),
  array('number' => 3),
  array('number' => 4),
  ...
  array('number' => 5000)
);

and the $second has 16000 rows and looks like:

array(
  array('key' => 1, 'val' => 'something'),
  array('key' => 2, 'val' => 'something'),
  array('key' => 3, 'val' => 'something'),
  ...
  array('key' => 16000, 'val' => 'something'),
)

I want to create a third array that contains $second[$i]['val'] IF $second[$i][$key] is in $first[$i][$number]

currently I am doing:

$third = array();
foreach($first as &$f)
  $f = $f['number'];

foreach($second as $s){
  if(in_array($s['key'], $first)
    $third[] = $s['val];
}

but, unless I use php's set_timeout(0) it is timing out, is there a more efficient way?


Solution

  • $third = array();
    $ftemp = array();
    foreach($first as $f)
      $ftemp[$f['number']] = true;
    
    foreach($second as $s){
      if(isset($ftemp[$s['key']]))
        $third[] = $s['val'];
    }
    

    should be waaay faster.

    Don't try to make lookup dictionary in more convoluted way like below, because it actually is slower than above straightforward loop:

    $third = array();
    $ftemp = array_flip(reset(call_user_func_array('array_map', array_merge(array(null), $first))));
    // $ftemp = array_flip(array_map('reset', $first)); // this is also slower
    // array_unshift($first, null); $ftemp = array_flip(reset(call_user_func_array('array_map', $first))); // and this is even slower and modifies $first array
    
    foreach($second as $s){
      if(isset($ftemp[$s['key']]))
        $third[] = $s['val'];
    }