-1

Can someone tell me what is wrong with this code :

foreach ($data as $region ):

  foreach ($region as $type):

   foreach ($type as $type2):

    foreach ($type2 as $key=>$val):

    if ($val=='background-color: FFFFFF;' || $val=='')  unset($type2[$key]);

    endforeach;

   endforeach;

  endforeach;

endforeach;

After print_r($data) seems that the data array is the same and unset is not working

deceze
  • 510,633
  • 85
  • 743
  • 889
user2029029
  • 51
  • 1
  • 4

2 Answers2

2

Your loop is operating on copies of the original elements; changes to $type2 will not be visible in $data because $type2 is a copy.

You can solve this by iterating over all arrays by key, then indexing into $data with those keys to remove the value:

foreach ($data as $k1 => $region ):

  foreach ($region as $k2 => $type):

   foreach ($type as $k3 => $type2):

    foreach ($type2 as $k4 =>$val):

    if ($val=='background-color: FFFFFF;' || $val=='') {
        unset($data[$k1][$k2][$k3][$k4]);
    }

    endforeach;

   endforeach;

  endforeach;

endforeach;

Of course this is ugly, but that's four nested loops will do. There is also the option if iterating by reference instead of grabbing keys, but personally I dislike that because of the nice opportunity to write bugs by reusing the abandoned references after the loop has ended. Especially in this case I dislike it to the fourth power.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • Especially in this case i dislike your method, because you generate alot of copies (depending on array sizes of course), which takes MUCH more cpu time (and some more RAM) than passing a reference. and the only advantage that you noted for that is that bad code after that will not be as bad (as far as i understood that) – x4rf41 Aug 08 '13 at 11:12
  • @x4rf41: PHP uses copy-on-write, so we are talking about very lightweight copies (only extra ZVALs are created) -- it's exactly the same as when iterating by reference, both as regards CPU time and RAM. Where do you base your assertions? – Jon Aug 08 '13 at 11:41
  • @x4rf41: Actually, what happens is exactly the reverse. Compare [this](http://ideone.com/q5BQHr) to [this](http://ideone.com/a6ZM2R). References in PHP should be used *very* sparingly and only if you know exactly what you are doing. I was surprised myself to see how bad references are in this case. – Jon Aug 08 '13 at 11:52
  • Tks Jon your code is working just fine ! x4rf41, i know that this code is not "to optimal" or elegant but im looping trough a small size array so performance shouldnt be affected. – user2029029 Aug 08 '13 at 17:34
-1

use this, it should work:

foreach ($data as &$region ):

  foreach ($region as &$type):

   foreach ($type as &$type2):

    foreach ($type2 as $key=>$val):

    if ($val=='background-color: FFFFFF;' || $val=='')  unset($type2[$key]);

    endforeach;

   endforeach;

  endforeach;

endforeach;

the array values are passed as reference because of the & i put before the value variables. The unset will work this way

x4rf41
  • 5,184
  • 2
  • 22
  • 33