Frage

Wenn ich die folgende Anweisung ausführe:

@filtered = map {s/ //g} @outdata;

Es wird eine leere Liste anstelle der erwarteten gefilterten Liste zurückgegeben.Ich versuche, jedes Vorkommen von zu entfernen   aus einem String-Array (das eine XML-Datei ist).

Offensichtlich verstehe ich etwas nicht.Kann mir jemand sagen, wie das richtig gemacht werden könnte und warum das bei mir nicht so funktioniert, wie es ist?

War es hilfreich?

Lösung

Versuche dies:

@filtered = map {s/ //g; $_} @outdata;

Das Problem besteht darin, dass der s-Operator in Perl $_ ändert, aber tatsächlich die Anzahl der vorgenommenen Änderungen zurückgibt.Das zusätzliche $_ am Ende bewirkt also, dass Perl die geänderte Zeichenfolge für jedes Element von @outdata zurückgibt.

Andere Tipps

Beachten Sie, dass „map“ auch Ihr Quellarray ändert.Sie können also entweder Folgendes tun:

map {s/ //g} @outdata;

und überspringen Sie die @filtered-Variable ganz, oder wenn Sie die Originale behalten müssen,

@filtered = @outdata;
map {s/ //g} @filtered;

Obwohl es in diesem Fall möglicherweise besser lesbar ist, foreach zu verwenden:

s/ //g foreach @filtered;

Gregs Antwort hat das Problem, dass das ursprüngliche Array geändert wird, wenn $_ als Alias ​​übergeben werden.Du brauchst:

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;

Um Tithoniums Argument weiterzuverfolgen: Dies wird auch den Zweck erfüllen:

@filtered = map {local $_=$_; s/ //g; $_} @outdata;

„Lokal“ stellt sicher, dass Sie an einer Kopie und nicht am Original arbeiten.

In Perl 5.14 könnten Sie das verwenden /R Regex-Modifikator für Nehmen Sie eine zerstörungsfreie Substitution vor.

@filtered = map {s/ //gr} @outdata;
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;

Als Kontrapunkt zu Gregs Antwort könnten Sie grep missbrauchen:

@filtered = grep {s/ //g; 1} @outdata;

Tun Sie das nicht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top