как это работает: карта используется с оператором троичного крючка и () - PullRequest
5 голосов
/ 27 февраля 2011

В предыдущем вопросе seaworthy спросил, как удалить первые 5 элементов из массива: Как удалить первые пять элементов массива?

Среди нескольких предложений, Фридо предложил следующее:

my $cnt = 0; @array = map { ++$cnt < 5 ? ( ) : $_ } @array;

Я не понимаю бит (). Пожалуйста, могли бы объяснить, как это работает для меня, потому что я не могу обдумать это?

Я знаю, что троичный оператор ловушки работает так: (если что-то) ? (затем сделайте это): (в противном случае сделайте это)

Например: $a=2; print ($a==2 ? 3 : 4) # это печатает: 3 потому что у нас есть: ($ a == 2? 3: 4) что означает: (если $ a равно 2)? (затем выведите 3): (в противном случае выведите 4)

так что с кодом Friedo сначала $ cnt увеличивается до 1, затем мы имеем:

$cnt < 5 ? ( ) : $_ что значит: if $cnt is less than 5 ? then ( ) : otherwise $_

Я вижу, как работает бит $ _, потому что иногда я использую карту следующим образом:

@array = map { $_, "\n" } @array

Это копирует элемент из @array, помещает копию в $ , затем добавляет новую строку \ n, затем копирует значение в $ обратно в @array (и делает это со всеми значениями в @array, поэтому в основном он добавляет новые строки к каждому элементу @array)

поэтому:
@array = map { if $cnt is less than 5 then ( ) otherwise $_ } @array

означает что-то вроде:
@array = map { if $cnt is less than 5 then ( ) otherwise copy the element back to @array }

так ясно () означает что-то вроде «избавиться от этого» но я просто не уверен, как это работает. Пожалуйста, не могли бы вы объяснить это?

Ответы [ 3 ]

10 голосов
/ 27 февраля 2011

В 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;
2 голосов
/ 16 июня 2011

Я знаю, что немного опаздываю в игре, но почему бы не сделать что-нибудь простое?

my @truncated = @array [5 .. $ # array]

1 голос
/ 27 февраля 2011

Очевидно, что вы можете вернуть список вместо элемента, а map создает результат, объединяя эти списки и элементы.() - это просто пустой список в этом случае.Для большей наглядности скопируйте и вставьте пример и замените () на (1, 2, 3).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...