2
Array
(
    [1] => 1
    [2] => 1
    [3] => 1
    [4] => 1
    [5] => 0
    [6] => 1
    [7] => 0
    [8] => 0
)

Should do this: (completly delete previous elements)

    found [5] => 0 then unset [4] => 1 and unset [5] => 0
    found [7] => 0 then unset [6] => 1 and unset [7] => 0
    found [8] => 0 then unset [3] => 1 (because 7,6,5,4 were already deleted) 
    and  unset[8] => 0

Result:

Array
(
    [1] => 1
    [2] => 1
)

I've tried something like this, but it unsets only the current element, why?

foreach ($points as $key => $value) {
    if ($value == '0') {
        unset($points[$key]);
        $prev = prev($points);
        unset($prev);
    } 
}
Puristaako
  • 101
  • 6

1 Answers1

4

When you iterate the array with foreach you can not navigate as well with prev - because the array has only one pointer and foreach and prev will battle on it.

You need to choose a compatible way.

Using array functions (reset, current, key, prev, next, end)

For example only with the array functions:

for(
    reset($points);
    $value = current($points), $key = key($points), $key !== null;
    next($points)
) {
    if ($value == '0') {
        unset($points[$key]);
        prev($points);
        $key = key($points);
        if ($key === null) {
            end($points);
            $key = key($points);
        }
        unset($points[$key]);
        prev($points);
    }
}

Result:

Array
(
    [1] => 1
    [2] => 1
)

There are some caveats:

  • unset($prev) does only unset the variable, you want to unset the array entry
  • When the last element is removed, prev() does not work any longer. This is why end() is used to jump to the last element.

Using foreach with a stack of keys

This is an alternative way using foreach. An additional stack with the keys that were iterated over previously with correct values is kept so previous values can be removed (until there aren't any previous values):

$lastKeys = [];
foreach ($points as $key => $value)
{
    if ($value == '0') {
        $lastKey = array_pop($lastKeys);
        if ($lastKey !== null) {
            unset($points[$lastKey]);
        }
        unset($points[$key]);
        continue;
    }
    $lastKeys[] = $key;
}
hakre
  • 193,403
  • 52
  • 435
  • 836
  • `unset($prev);` does nothing in your code (except unset the local variable `$prev` but not the element of the array it represents) – kero Dec 22 '14 at 22:58
  • 2
    The other reason `foreach` and `prev` don't work together is because `foreach` uses a copy of the array. – Barmar Dec 22 '14 at 22:59
  • @kingkero: Yes, fixed. – hakre Dec 22 '14 at 23:00
  • 1
    @Barmar: Not always / really, I didn't want to go into detail with that. (glory details are here: http://stackoverflow.com/q/10057671/367456) – hakre Dec 22 '14 at 23:00
  • You don't seem to be getting the same final result. But maybe it's because your array has a `[0]` element that wasn't in the question. – Barmar Dec 22 '14 at 23:02
  • @Barmar: Yes, I had it zero indexed, however, I still get three values instead of two. That is because if the last element is removed, `prev` doesn't work any longer. will fix that. – hakre Dec 22 '14 at 23:05
  • I guess you need to remove the previous element before removing the current element. – Barmar Dec 22 '14 at 23:07
  • problem is if you don't know if there was a previous element in that order. according to the specs in the question, better first remove, then move to the previous one. exactly as told :) – hakre Dec 22 '14 at 23:10