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

Когда я запускаю следующее заявление:

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

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

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

15.08.2008 09:38:31
Это относится к stackoverflow.com/questions/1458454/… и имеет тот же ответ.
brian d foy 17.08.2015 18:17:31
7 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

10
15.08.2008 09:49:17
Я не чувствую себя достаточно подлым, чтобы понизить голос, но это плохая идея. stackoverflow.com/questions/12103/… гораздо лучший ответ.
Rob Van Dam 2.01.2010 08:54:29
С помощью неразрушающего замещения в Perl 5.14 вы можете делать это, @filtered = map { s/ //gr } @outdataне затрагивая @outdata.
brian d foy 17.08.2015 18:19:18

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

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

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

3
17.08.2008 15:51:55

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

map {s/ //g} @outdata;

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

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

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

s/ //g foreach @filtered;
15
22.08.2008 04:51:03
mapв пустом контексте обычно считается плохой формой и не говорит ничего сверх for @filtered { ... }.
brian d foy 17.08.2015 18:21:24

Чтобы прокомментировать точку зрения Титония, это также поможет:

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

«Местный» гарантирует, что вы работаете с копией, а не с оригиналом.

6
15.09.2008 14:04:43

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

@filtered = map { (my $new = $_) =~ s/ //g; $new} @outdata;
9
3.01.2010 17:53:20
use Algorithm::Loops "Filter";
@filtered = Filter { s/ //g } @outdata;
4
1.12.2008 03:35:43

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

@filtered = map {s/ //gr} @outdata;
5
18.05.2012 17:31:29