Почему моя карта Perl ничего не возвращает?

Когда я выполняю следующее утверждение:

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

он возвращает пустой список вместо отфильтрованного списка, который я ожидал. Я пытаюсь удалить каждое вхождение   из массива строк (который представляет собой XML-файл).

Очевидно, я чего-то не понимаю. Может ли кто-нибудь подсказать мне правильный способ сделать это, и почему это не работает для меня как есть?

Комментарии к вопросу (1)

Обратите внимание, что map также изменит ваш исходный массив. Поэтому вы можете либо сделать:

map {s/ //g} @outdata;

и вообще пропустить переменную @filtered, либо, если вам нужно сохранить оригиналы,

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

Хотя в этом случае, возможно, будет более читабельно использовать foreach:

s/ //g foreach @filtered;
Комментарии (1)
Решение

Попробуйте это:

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

Проблема в том, что оператор s в perl модифицирует $, но на самом деле возвращает количество сделанных изменений. Таким образом, дополнительный $ в конце заставляет perl возвращать измененную строку для каждого элемента @outdata.

Комментарии (3)

Грег'ы ответ есть проблема, что она будет изменять исходный массив как $_ передаются псевдоним. Вам нужно:

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;
Комментарии (0)

Следить за Tithonium's точки, это будет также сделать трюк:

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

В "местных" и гарантирует, что вы'вновь работает с копией, а не оригиналом.

Комментарии (0)

В Perl 5.14 можно использовать регулярное выражение модификатор сделать неразрушающей замены.

@filtered = map {s/ //gr} @outdata;
Комментарии (0)
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;
Комментарии (0)

В качестве контраргумента к ответу Грега, вы можете неправильно использовать grep:

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

Не делайте этого..

Комментарии (0)