次のステートメントを実行しているとき:
@filtered = map {s/ //g} @outdata;
期待していたフィルタリングされたリストではなく、空のリストが返されます。私がやろうとしているのは
、文字列の配列(XMLファイル)からすべての出現箇所を削除することです。
明らかに、私は何かを理解していません。誰かがこれを行う正しい方法を教えてもらえますか、そしてなぜこれが私にとってそのままでは機能しないのですか?
マップはソース配列も変更することに注意してください。したがって、次のいずれかを行うことができます。
map {s/ //g} @outdata;
@filtered変数を完全にスキップするか、元の変数を保持する必要がある場合は、
@filtered = @outdata;
map {s/ //g} @filtered;
ただし、その場合は、foreachを使用する方が読みやすい場合があります。
s/ //g foreach @filtered;
これを試して:
@filtered = map {s/ //g; $_} @outdata;
問題は、perlのs演算子が$ _を変更するが、実際にはそれが行った変更の数を返すことです。したがって、最後に余分な$ _があると、perlは@outdataの各要素の変更された文字列を返します。
グレッグの答えには、 $_ がエイリアスとして渡されるため、元の配列が変更されるという問題があります。必要なもの:
@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;
ティソニウムのポイントをフォローアップするために、これはまたトリックを行います:
@filtered = map {local $_=$_; s/ //g; $_} @outdata;
「ローカル」は、オリジナルではなく、コピーで作業していることを保証します。
perl 5.14 では、/r regex 修飾子を使用して非破壊置換を行うことができました。
@filtered = map {s/ //gr} @outdata;
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;
Greg の回答に対する反論として、grep を誤用する可能性があります。
@filtered = grep {s/ //g; 1} @outdata;
これをしないでください。