В map
каждый элемент массива передается в блок кода (в $_
), где он может быть преобразован в какое-то другое значение.Другими словами, map
преобразует список.
В этом случае мы хотим отбросить значения, в которых число ($cnt
) меньше 5. Итак, как нам сделать блок map
вернуть «ничто», когда это условие истинно?
Мы не можем сказать
my $cnt = 0; @array = map { ++$cnt < 5 ? undef : $_ } @array;
Потому что тогда мы получим массив, который выглядит как
( undef, undef, undef, undef, undef, 6, 7, 8 ... )
это не то, что мы хотели.
Но возвращение ( )
вместо этого возвращает пустой список .Рассмотрим push @foo, ( );
или @bar = ( 1, 2, 3, ( ), 4, 5, 6 );
. В каждом из этих случаев пустой набор скобок представляет собой список нулевых элементов, который не оказывает никакого влияния на соответствующие массивы.
Пустой список полезен втроичные, где вам нужно либо вернуть элемент списка, либо ничего вообще.Также полезно принудительно использовать контекст списка в выражении, чтобы получить счетчик:
my $count = ( ) = $str =~ /\d/g;
Здесь мы помещаем регулярное выражение в контекст списка, назначая его пустому списку, давая нам количество цифр в строке,Затем мы присваиваем этот пустой список $count
.
Другой частый пример использования списков в map
- это когда вы преобразовываете что-то в хеш.Например,
my %unique = map { $_ => 1 } @duplicates;
Здесь каждый отдельный элемент в @duplicates
преобразуется в двухэлементный список, который выглядит как ( 'foo' => 1 )
, хотя это не так очевидно, так как в этом нет никаких символов.Все списки из двух элементов затем объединяются в один большой список чередующихся ключей и значений, которые составляют хэш.Допустим, вы хотели создать этот хеш, но исключили некоторые элементы.В этом случае нам либо нужно вернуть ключ / значение, либо ничто .Так что это хороший шанс использовать пустой список:
my %filtered_unique = map { some_test( $_ ) ? ( ) : ( $_ => 1 ) } @duplicates;