BinSpeak

dev@blog

Elemente eines Arrays löschen

November 4th, 2008 by Frobenius

Gerade hatte ich mal wieder ein kleines Problem bei dem Versuch mehrere Elemente in einer Iteration aus einem Array zu löschen. Den Fehler hab ich schon öfters gemacht und doch denke ich im ersten Moment nie daran. Folgendes (vereinfacht) habe ich gemacht (hier in PHP):

    $a = array(2,2,1);
    $cnt = count($a);
    for($i = 0; $i < cnt; $i++) {
        if($a[$i] == 2) {
            array_splice($a, $i, 1);
        }
    }
    var_dump($a);
 
/*  Ausgabe:
array(2) {
   [0] =>
   int(2)
   [1] =>
   int(1)
}
*/

Der Versuch alle Elemente, die 2 sind zu löschen ging schief, weil man das Array selbst während der Iteration geändert hat. Nachdem man den ersten Eintrag gelöscht hat, steht $i auf 1, an Index-Position 1 des Array ist jetzt aber nicht die zweite 2, sondern die 1, weil ja das Array nur noch zwei Elemente hat. Die Lösung für das Problem ist ganz einfach (auch ohne foreach). Man geht einfach rückwärts durch das Array:

    $a = array(2, 2, 1);
    for($i = count($a)-1; $i >= 0; $i--) {
        if($a[$i] == 2) {
             array_splice($a, $i, 1);
        }
    }

    var_dump($a);
/* Ausgabe:
array(1) {
  [0] =>
  int(1)
}
*/

Diesmal geht alles gut, weil wir nach dem löschen eines Elements nur Indizies betrachten, die vor dem gelöschten liegen, und damit nicht von dessen Löschung beinflusst werden.

Als zweite Variante bietet sich an, in der ersten Schleife anstatt array_splice die Funktion unset zu verwenden, die löscht nämlich den Wert im Array, passt aber die Indizes nicht an. Das ist imho ein ziemlich bescheuertes Verhalten, aber in diesem Fall nützlich. Nach dem löschen muß man dann allerdings aufpassen, weil es gibt kein $a[0] Element mehr, sondern nur noch ein $a[2] Element.

This entry was posted on Dienstag, November 4th, 2008 at 00:09 and is filed under general. You can follow any responses to this entry through the RSS 2.0 feed. Responses are currently closed, but you can trackback from your own site.

Comments are closed.