Removing a value in an array, six methods

Removing one value is a classic task, and it is quite natural to discover multiple ways to do so. Then, you can choose the one that suits your coding style the best.

Usually, alternatives algorithms come with different limitations : speed, memory usage, extensions… In this article, we’ll focus on the following set up :

<?php

$haystack = range('a', 'z'); 
$needle = 'b';

?>

We want to remove the letter b in the alphabet. Any other letter should be able to replace b, though we expect it to be available in that list, and only once. The availability will allow the skipping of existence tests, while they should be explicit in real code.

Here are the six alternatives :

  • array_search()
  • array_diff()
  • array_filter()
  • array_keys()
  • array_flip()
  • foreach()

In fact, arrayflip(), foreach, arrayfilter() have double, though they are not different enough to appear twice in this list.

Let’s go!

array_search()

array_search() looks for the key associated to a value in an array. With this key, we can then remove the index in the array. Here, we also know that the key will be found, as we know it is in that list : real code would add a check to skip unset() when the id is not found.

<?php

    $id = array_search('b', $a);
    unset($a[$id]);

?>

array_diff()

array_diff() removes all the values in the first array that are present in the second array. Here, since we are looking for a single value, that second array is a small array.

Kudos to the fact that zero, one or more values are removed from the initial array : this works even if the value is not available. Also note that a new array is produced : the original array is not modified.

<?php

    $a = array_diff($a, ['b']);

?>

array_filter()

arrayfilter() is the older cousin of arraydiff() : instead of making a direct comparison between values in two array, it applies a closure on each element, and keep the one that are true.

Here, the closure is very simple, but in real life, it is convenient for complex calculations. Closure, use expression and arrow functions are all possible here.

<?php

    // with use
    $c = array_filter($a, function($x) use ($b) { return $x !== $b;});

    // without use
    $c = array_filter($a, function($x) { return $x !== 'b';});

    // without fn
    $c = array_filter($a, fn($x) =&gt; $x !== 'b';);

?>

array_keys()

array_keys() has a second arguments that is rarely used : it is a filter value, that limits the returned keys to the one that hold that value. This is exactly what we need here, lest one detail : there is only one to remove. Then, we can get that first key straight at index 0.

arraykeys() then works a bit like arraydiff(), but with an extra step.

<?php

    $ids = array_keys($a, 'b');
    $c = $a;
    unset($c[$ids[0]]);
    
?

array_flip()

array_flip() flips an array : keys becomes values, and values becomes keys. Which means that instead of searching for ‘b’ in the values, we can now use it as an index, and get it location in the original array.

array_flip() is often a shiny toy with index and values manipulations, though it often comes with caveats. In this article, values being strings and unique, it works quite well. In case there are multiple identical values, all but one will be lost. And in case some of the strings look like a number, such as ‘1’, or ‘1e3’, there will be type juggling.

Knowing that, it works.

<?php

    $c = array_flip($a);
    unset($a['b']);
    
?>

foreach()

Last, but not least, is our good friend foreach(). Often, foreach() is faster than a function call, as all of this happens in the same context. In this case, there might be a lot of copying or checking, so that advantage tend to be limited.

Two alternative : either spot the value in the code and remove it, or rebuild the whole array.

<?php

    $c = [];
    foreach($a as $k =&gt; $v) {
        if ($v !== 'b') {
            $c[$k] = $v;
        }
    }   

?>

Speed checks

The amount of code to write is illustrated in the code above, so you can make up your mind about which will save you more keystrokes than the other.

As for speed, here is the final ranking, over a million runs, and 26 elements in the array :

  1. array_search() : 81.59 mseconds
  2. array_diff() : 217.00 mseconds
  3. array_flip() : 220.48 mseconds
  4. array_keys() : 226.73 mseconds
  5. array_flip() (twice) : 298.21 mseconds
  6. foreach() (unset) : 465.73 mseconds
  7. foreach() (rebuild) : 665.78 mseconds
  8. array_filter() : 919.68 mseconds
  9. array_filter() use : 1,057.45 mseconds
  10. array_filter() fn : 1,044.57 mseconds

All of them are a micro-optimisation, although it is interesting to see the difference in required processing time to reach the same result.

Another interesting take is that some of those algorithms will not adapt easily to multiple ‘b’ in the array, or when removing multiple distinct values [‘b’, ‘e’, ‘p’]… Evolutivity may be important.

arraysplice() could also have been used, instead of unset(), when that call is explicit. Though, arraysplice() is not performant on such small size, so it was left out of this article.