php – Most optimized way to filter large multidimensional array with large indexed array-ThrowExceptions

Exception or error:

Both of my arrays have over 500 000 elements.

I would like to return only those elements from multidimensional array that ARE NOT PRESENT in indexed array.

Here is what my multidimensional array looks like:

$new_codes = [
   0 => [
            'id' => 1,
            'code' => 'code1',
            ... another values
   ],
   1 => [
            'id' => 2,
            'code' => 'code2',
            ... another values
   ],
   2 => [
            'id' => 3,
            'code' => 'code3',
            ... another values
   ]
];

Another array is just plain indexed array with code values:

$old_codes = [
      'code1',
      'code2',
];

For this limited example, after filtering, $new_codes should only have index 2 because that value doesn’t exist in $old_codes array.

I’ve tried using the code bellow, but because the arrays are so huge, the operation takes so long that I thought that I somehow created infinite loop, but it seems that checking if the values for over 500000 elements exist in another array that also has over half a million elements takes very long time.

// option 1
$new = array_filter($new_codes, function ($var) use ($old_codes) {
            return !in_array($var['code'], $old_codes);
        });

// option 2
$filtered = [];
foreach($new_codes as $code) {
    if(in_array($code['code']){
         continue;
     }

    $filtered[] = $code;
}

Any suggestions for more optimized solutions are welcome.

Thanks in advance.

How to solve:

Reading this question I realized that using isset() is much better option for handling such a large amount of elements so I did this:

// switch array keys and values
$old_array = array_flip($old_array);

foreach($new_codes as $code) {
    if(isset($old_array[$code['code']])){
         continue;
     }

    $filtered[] = $code;
}

Doing this reduced the time to just few seconds.

Leave a Reply

Your email address will not be published. Required fields are marked *