Home » Php » optimization – What is the most elegant way to do "foreach x except y" in PHP?

optimization – What is the most elegant way to do "foreach x except y" in PHP?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I want to do something like this:

foreach ($array as $key=>$value except when $key="id")
{
// whatever

}

… without having to put an “if” clause inside the body of the loop. It is not guaranteed that “id” will the be the first or last element in the array, and I don’t really want to unset or slice the array, because that will be expensive, ugly, and not maintain the original data. I also definitely need to use both key and value inside the loop.

Any ideas?

How to&Answers:

I don’t think that the if-clause is such a problem:

foreach ($array as $key => $value) {
    if ($key == 'ignore_me') continue;
    if ($key == 'ignore_me_2') continue;

If you want a fancy solution, you can use array_diff_key:

$loop_array = array_diff_key($actual_array, array('ignore_me' => NULL, 'ignore_me_2' => NULL));
foreach ($loop_array as $key => $value) {
    #...

Answer:

Go with the if-clause inside the loop.
There is nothing inelegant about it, it is the easiest to read and understand, and it is the most efficient.

If you have many keys to skip you could build a second hash to test against (in the if-clause):

foreach ($array as $key => $value) {
   if (array_key_exists($key,$skip_keys)) continue;
   ...
}

Answer:

I think you’ll always end up to use an IF clause in the inner loop. Of all the options you already gave, that’s the only one I would use for the speed and the memory consumption

Answer:

AFAIK you can’t do it without an if in the loop.

Like the keyword says, it’s “for each”, not “for most”.

EDIT: like soulmerge says, you could do it with array_diff_key(), but if you’re only missing out a single key it’s more verbose and less memory efficient than just putting the if in the loop.

Answer:

Another way of compacting the if statement is:

// ignore 1,5,8,9
foreach($arr as $key){
  if(in_array($key, array(1,5,8,9)) continue;
  ...
}