Pourquoi ma carte Perl ne renvoie-t-elle rien ?
Question
Lorsque j'exécute l'instruction suivante :
@filtered = map {s/ //g} @outdata;
il renvoie une liste vide au lieu de la liste filtrée à laquelle je m'attendais.Ce que j'essaie de faire, c'est de supprimer chaque occurrence de
à partir d'un tableau de chaînes (qui est un fichier XML).
Visiblement, je ne comprends pas quelque chose.Quelqu'un peut-il me dire quelle est la bonne façon de procéder et pourquoi cela ne fonctionne pas pour moi tel quel ?
La solution
Essaye ça:
@filtered = map {s/ //g; $_} @outdata;
Le problème est que l'opérateur s en Perl modifie $_ mais renvoie en réalité le nombre de modifications apportées.Ainsi, le $_ supplémentaire à la fin amène Perl à renvoyer la chaîne modifiée pour chaque élément de @outdata.
Autres conseils
Notez que map va également modifier votre tableau source.Vous pouvez donc soit faire :
map {s/ //g} @outdata;
et ignorez complètement la variable @filtered, ou si vous devez conserver les originaux,
@filtered = @outdata;
map {s/ //g} @filtered;
Bien que, dans ce cas, il pourrait être plus lisible d'utiliser foreach :
s/ //g foreach @filtered;
La réponse de Greg a le problème qu'elle modifiera le tableau d'origine lorsque les $_ seront transmis avec un alias.Vous avez besoin:
@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;
Pour faire suite au point de Tithonium, ceci fera également l'affaire :
@filtered = map {local $_=$_; s/ //g; $_} @outdata;
Le « local » garantit que vous travaillez sur une copie et non sur l'original.
En Perl 5.14, vous pouvez utiliser le /r modificateur d'expression régulière à effectuer une substitution non destructive.
@filtered = map {s/ //gr} @outdata;
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;
En contrepoint à la réponse de Greg, vous pourriez abuser de grep :
@filtered = grep {s/ //g; 1} @outdata;
Ne fais pas ça.