0

I have some code I created which is supposed to see if something exists in an array of strings. If it does not exist, I want to delete that element of the array. I thought we do this with unset, but it doesnt seem to be working. Mind helping?

echo '<br>size of $games before end-check: '.sizeof($games);
foreach ($games as $game) {
    $game_end_marker = "body = (game)#";
    $game_end_pos = strpos($game, $game_end_marker);
    if ($game_end_pos !== false) {
        echo "<br>end of game found";
    } 
    else {
        echo "<br>end of game not found. incomplete game";
        unset($game);
    }
}
echo '<br>size of $games after end-check: '.sizeof($games);

output:

size of $games before end-check: 2  
end of game found  
end of game not found. incomplete game  
size of $games after end-check: 2  
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
pr0tocol
  • 323
  • 1
  • 4
  • 14
  • you should unset from $games not $game, $game is temporary created by the foreach function. –  Dec 21 '11 at 18:51
  • Refer this answer: [How to delete an element from an array in php?](http://stackoverflow.com/a/369761/500725) – Siva Charan Dec 21 '11 at 18:56

6 Answers6

4

Because you unset the variable $game, not the element in the array. Try this:

echo '<br>size of $games before end-check: '.sizeof($games);
foreach ($games as $index => $game) {
    $game_end_marker = "body = (game)#";
    $game_end_pos = strpos($game, $game_end_marker);
    if ($game_end_pos !== false) {
        echo "<br>end of game found";
    } 
    else {
        echo "<br>end of game not found. incomplete game";
        unset($games[$index]);
    }
}
echo '<br>size of $games after end-check: '.sizeof($games);
ocirocir
  • 3,543
  • 2
  • 24
  • 34
  • This did the trick, and I learned how to do this now with $key => $value in a foreach loop. Thanks! – pr0tocol Dec 21 '11 at 19:05
2

You have to unset the index of game.

foreach ($games as $key => $value) {
  // all your logic here, performed on $value
  unset($games[$key]);
}
dm03514
  • 54,664
  • 18
  • 108
  • 145
2

This merely unsets your local reference to the element. You need to be referring directly to the array.

foreach($games as $key => $game)
    unset($games[$key]);
Alex Turpin
  • 46,743
  • 23
  • 113
  • 145
0

That won't work: foreach creates a new variable, copying the old one. Unsetting it will do nothing to the original value. Likewise, making it a reference won't work either, since only the reference would be deleted.

The nicest way to do this would be with array_filter:

$games = array_filter($games, function($game) {
    $game_end_marker = "body = (game)#";
    $game_end_pos = strpos($game, $game_end_marker);

    if ($game_end_pos !== false) {
        echo "<br>end of game found";
        return true;
    } 
    else {
        echo "<br>end of game not found. incomplete game";
        return false;
    }
});

This uses the anonymous function syntax introduced in PHP 5.3. If the function returns true, the element is kept; if it returns false, the element is removed.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
  • I marked the answer above, and this is incorrect per the implemented solution results. Using `foreach ($games as $index => $game)`, I was able to do `unset($games[$index])` and it persisted outside of the foreach loop. – pr0tocol Dec 21 '11 at 19:08
0

You can also call by reference:

foreach($games as &$game) {
    unset($game);
}

In this way you can also change $game (eg. $game .= " blah";) and the original array will be modified.

Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

You can use array_splice in conjunction with an incrementally-increasing index variable to remove the current item from the array:

$index = 0;
foreach ($games as $game) {
    $game_end_marker = "body = (game)#";
    $game_end_pos = strpos($game, $game_end_marker);
    if ($game_end_pos !== false) {
        echo "<br>end of game found";
    } 
    else {
        echo "<br>end of game not found. incomplete game";
        array_splice($games, $index, 1);
    }
$index++;
}
Aaron
  • 5,137
  • 1
  • 18
  • 20