ein delete() auf Elemente eines Array angewendet l�scht ja den
angegebenen Index, ohne die restlichen Indices anzulangen. Muss man nun
das alte Array Index f�r Index in ein neues kopieren, um die L�cken zu
schliessen, oder gibt es daf�r eine Funktion?
Danke und Gru�, Helmut
--
No Swen today, my love has gone away
My mailbox stands for lorn, a symbol of the dawn
Ja! perldoc -f splice
perldoc -f delete
Das verweist dich auch auf splice, wie Tobias schon geschrieben hat. Ich
m�chte eigentlich nur noch hinzuf�gen, dass ich pers�nlich splice
�u�erst selten ben�tige - es ist ja auch keine billige Operation.
Dabei f�llt mir gerade noch auf, dass perldoc -f splice im Beispiel
folgenden Code enth�lt:
sub aeq { ... }
if (&aeq(...)) { ... }
Also die Funktion unn�tigerweise mit & aufgerufen wird. Wo/wem kann ich
vorschlagen, dass das & entfernt wird?
Wolf
Verhält sich splice "unerwartet", oder ich mich?
use Data::Dumper;
my @array = qw(A B C BD E BE F G B);
my $index = 0;
print "Array before:\n" . Dumper(@array) . "\n";
foreach my $entry (@array) {
print "Current \$entry: $entry\n";
unless ($entry =~ m/B/i) {
print "Removing \$array[$index]: $array[$index]\n";
splice(@array, $index, 1);
} else {
print "Increasing \$index: $index\n";
$index++;
}
}
print "\nArray after:\n" . Dumper(@array) . "\n";
# perl ./test.pl
Array before:
$VAR1 = 'A';
$VAR2 = 'B';
$VAR3 = 'C';
$VAR4 = 'BD';
$VAR5 = 'E';
$VAR6 = 'BE';
$VAR7 = 'F';
$VAR8 = 'G';
$VAR9 = 'B';
Current $entry: A
Removing $array[0]: A
Current $entry: C
Removing $array[0]: B
Current $entry: E
Removing $array[0]: C
Current $entry: F
Removing $array[0]: BD
Current $entry: B
Increasing $index: 0
Array after:
$VAR1 = 'E';
$VAR2 = 'BE';
$VAR3 = 'F';
$VAR4 = 'G';
$VAR5 = 'B';
#
Du dich.
Denn dein Fehler ist, dass du mit for (@array) loopst und innerhalb der
Loop dann Splice auf das Array verwendest, über das du loopst. Perldoc
schreibt dazu:
Zitat aus perldoc perlsyn:
If any part of LIST is an array, "foreach" will get very confused if you
add or remove elements within the loop body, for example with "splice".
So don't do that.
Zitat Ende
Für das, was du machen möchtest, eignet sich grep aber sowieso viel
besser als splice. Dann ist dein komplettes Programm ein Befehl.
Wolf
Du Dich. :-)
Hier stimmt's noch.
> Current $entry: C
> Removing $array[0]: B
Hier nicht mehr. foreach ist mit seinem internen Zähler schon einen
Schritt weiter, index nicht (weil index ja erst gesetzt wird, wenn
vorher kein Element entfernt wurde). Am einfachsten ist es wohl, wenn
Du kein foreach benutzt:
diff --git a b
index e019352..6499773 100644
--- a
+++ b
@@ -4,9 +4,10 @@ my @array = qw(A B C BD E BE F G B);
my $index = 0;
print "Array before:\n" . Dumper(@array) . "\n";
-foreach my $entry (@array) {
- print "Current \$entry: $entry\n";
- unless ($entry =~ m/B/i) {
+my $array_size = scalar @array;
+for (my $i = 0; $i < $array_size; $i++) {
+ print "Current entry: $array[$index]\n";
+ unless ($array[$index] =~ m/B/i) {
print "Removing \$array[$index]: $array[$index]\n";
splice(@array, $index, 1);
} else {
Einen schönen Bug gäbe es hier, wenn man nicht auf < $array_size prüfen
würde, sondern "direkt" auf < scalar(@array).
Das ist doch alles Murx so, mit Verlaub! Allein schon, weil du 2 Indizes
hast, $i und $index. Da blickt man doch nicht richtig durch!
Das kannst du leichter und nur mit einem Index machen, wenn du von
hinten anfängst die Elemente herauszuschmeißen. Aber auch dann ist das
immer noch schlechtes Perl.
Wie wäre es mit:
@array = grep /B/i, @array;
Das ist doch gleich viel lesbarer?!
- Wolf
Natürlich ist das Murks. Ich kann aber nicht ahnen, was zwischen den
Zeilen bei Helmut eventuell noch passiert, das haben Minimalbeispiele so
an sich.
> Das kannst du leichter und nur mit einem Index machen, wenn du von
> hinten anfängst die Elemente herauszuschmeißen. Aber auch dann ist
> das immer noch schlechtes Perl.
Ich wollte seine Struktur beibehalten, damit er den Fehler sieht. Und
es gab ja nicht nur meine eine Antwort, sondern auch noch Deine. Da
kann man sich dann prima alle nötigen Informationen raussuchen.
Das Problem bei zu viel Abstraktion ist nunmal, dass man Fehler die im
Detail stecken nicht mehr findet.
> Wie wäre es mit:
>
> @array = grep /B/i, @array;
>
> Das ist doch gleich viel lesbarer?!
Ja. Und wahrscheinlich reicht's ihm auch.
> Wie wäre es mit:
>
> @array = grep /B/i, @array;
Herje, so einfach...
Merci.
Die p5p Mailingliste oder http://rt.perl.org/perlbug/
hp