Какой смысл карты Perl?

Если у кого-то есть заявленная проблема, выполните следующие шаги в окне терминала:

  1. Перейдите к / Users / Имя пользователя / Библиотека / Android / sdk / platform- tools
  2. Выполнить ./adb root

Вот и все. Задача решена.

30
задан brian d foy 17 November 2008 в 03:33
поделиться

16 ответов

Любое время Вы хотите генерировать список, основывало другой список:

# Double all elements of a list
my @double = map { $_ * 2 } (1,2,3,4,5);
# @double = (2,4,6,8,10);

Так как списки легко преобразовываются попарно в хеши, если Вы хотите хеш-таблицу для объектов на основе конкретного атрибута:

# @user_objects is a list of objects having a unique_id() method
my %users = map { $_->unique_id() => $_ } @user_objects;
# %users = ( $id => $obj, $id => $obj, ...);

Это - инструмент действительно общего назначения, необходимо только начать использовать его для нахождения хорошего использования в приложениях.

Некоторые могли бы предпочесть подробный код цикличного выполнения в целях удобочитаемости, но лично, я нахожу map более читаемый.

44
ответ дан 27 November 2019 в 22:55
поделиться

Как другие сказали, карта является самой полезной для преобразования списка. То, что не было упомянуто, является различием между картой и "эквивалентом" для цикла.

Одно различие - то, что для не работает хорошо на выражение, которое изменяет список его итерация. Один из них завершается, и другой не делает:

perl -e '@x=("x"); map { push @x, $_ } @x'
perl -e '@x=("x"); push @x, $_ for @x'

Другая небольшая разница - то, что контекст в блоке карты является контекстом списка, но для цикла передает пустой контекст.

1
ответ дан 27 November 2019 в 22:55
поделиться

Вы используете карту, чтобы преобразовать список и присвоить результаты другому списку, grep, чтобы отфильтровать список и присвоить результаты другому списку. "Другой" список может быть той же переменной как список, который Вы преобразовываете/фильтруете.

my @array = ( 1..5 );
@array = map { $_+5 } @array;
print "@array\n";
@array = grep { $_ < 7 } @array;
print "@array\n";
4
ответ дан 27 November 2019 в 22:55
поделиться

Как другие сказали, карта создает списки из списков. Думайте об "отображении" содержания одного списка в другого. Вот некоторый код из программы CGI для взятия списка доступных чисел и гиперссылок печати к заявкам на патент:

my @patents = ('7,120,721', '6,809,505', '7,194,673');
print join(", ", map { "<a href=\"http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL&p=1&u=/netahtml/srchnum.htm&r=0&f=S&l=50&TERM1=$_\">$_</a>" } @patents);
1
ответ дан 27 November 2019 в 22:55
поделиться

Это используется каждый раз, когда требуется создать новый список из существующего списка.

, Например, Вы могли отобразить функцию парсинга в списке строк для преобразования их в целые числа.

3
ответ дан 27 November 2019 в 22:55
поделиться

Это позволяет Вам преобразовывать список как выражение, а не в операторах. Вообразите хеш солдат определенным как так:

{ name          => 'John Smith'
, rank          => 'Lieutenant'
, serial_number => '382-293937-20'
};

затем можно воздействовать на список имен отдельно.

Например,

map { $_->{name} } values %soldiers

выражение. Это может пойти куда угодно, выражение позволяется - кроме Вас, не может присвоить ему.

${[ sort map { $_->{name} } values %soldiers ]}[-1]

индексирует массив, беря максимум.

my %soldiers_by_sn = map { $->{serial_number} => $_ } values %soldiers;

Я нахожу, что одно из преимуществ операционных выражений - то, что это сокращает ошибки, которые прибывают из временных переменных.

Если г-н McCoy хочет отфильтровать всех Hatfield для рассмотрения, можно добавить, что сверяются с минимальным кодированием.

my %soldiers_by_sn 
    = map  { $->{serial_number}, $_ } 
      grep { $_->{name} !~ m/Hatfield$/ } 
      values %soldiers
      ;

Я могу продолжить объединять их в цепочку выражение так, чтобы, если мое взаимодействие с этими данными должно достигнуть глубоко конкретной цели, я не писал много кода, который притворяется, что я собираюсь сделать намного больше.

3
ответ дан 27 November 2019 в 22:55
поделиться

Генерируйте пароль:

$ perl -E'say map {chr(32 + 95 * rand)} 1..16'
# -> j'k=$^o7\l'yi28G
4
ответ дан 27 November 2019 в 22:55
поделиться

"Просто сахар" резок. Помните, цикл является просто сахаром - if's и goto могут сделать все, что конструкции цикла делают и т.д.

Карта является достаточно высокой функцией уровня, что она помогает Вам держать намного более сложные операции в голове, таким образом, можно кодировать и отладить большие проблемы.

5
ответ дан 27 November 2019 в 22:55
поделиться

Для перефразирования "Эффективного Программирования Perl" Hall & Schwartz картой можно злоупотребить, но я думаю, что это лучше всего используется для создания нового списка из существующего списка.

Создайте список квадратов 3,2, и 1:

@numbers = (3,2,1);
@squares = map { $_ ** 2 } @numbers;
4
ответ дан 27 November 2019 в 22:55
поделиться

Функция карты выполняет выражение на каждом элементе списка и возвращает результаты списка. Позволяет говорят, что у меня был следующий список

@names = ("andrew", "bob", "carol" );

, и я хотел использовать для своей выгоды первую букву каждого из этих имен. Я мог циклично выполниться через них и назвать ucfirst каждого элемента, или я мог просто сделать следующий

@names = map (ucfirst, @names);
5
ответ дан 27 November 2019 в 22:55
поделиться

карта используется для создания списка путем преобразования элементов другого списка.

grep используется для создания списка путем фильтрации элементов другого списка.

вид используется для создания списка путем сортировки элементов другого списка.

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

Для карты результат блока становится одним (или больше) элемент (элементы) в новом списке. Элемент тока искажается к $ _.

Для grep решает булев результат блока, будет ли элемент исходного списка скопирован в новый список. Элемент тока искажается к $ _.

Для вида блок получает два элемента (искаженный к $a и $b) и, как ожидают, возвратит один из-1, 0 или 1, указывая, больше ли $a, равен или меньше, чем $b.

Schwartzian Преобразовывают, использует эти операторы для эффективного кэширования значений (свойства), которые будут использоваться в сортировке списка, особенно когда вычисления этих свойств имеют нетривиальную стоимость.

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

Пример (создает список файлов в текущем каталоге, отсортированном ко времени их последнего изменения):

@file_list = glob('*');
@file_modify_times = map { [ $_, (stat($_))[8] ] } @file_list;
@files_sorted_by_mtime = sort { $a->[1] <=> $b->[1] } @file_modify_times;
@sorted_files = map { $_->[0] } @files_sorted_by_mtime;

Путем объединения в цепочку операторов вместе, никакое объявление переменных не необходимо для промежуточных массивов;

@sorted_files = map { $_->[0] } sort { $a->[1] <=> $b->[1] } map { [ $_, (stat($_))[8] ] } glob('*');

Можно также отфильтровать список прежде, чем отсортировать путем вставки grep (если Вы хотите отфильтровать на том же кэшируемом значении):

Пример (список файлов, измененных за прошлые 24 часа, отсортированные время последнего изменения):

    @sorted_files = map { $_->[0] } sort { $a->[1] <=> $b->[1] } grep { $_->[1] > (time - 24 * 3600 } map { [ $_, (stat($_))[8] ] } glob('*');
11
ответ дан 27 November 2019 в 22:55
поделиться

Это также удобно для того, чтобы сделать хеши поиска:

my %is_boolean = map { $_ => 1 } qw(true false);

эквивалентно

my %is_boolean = ( true => 1, false => 1 );

Там нет очень сбережений, но предположите, что Вы хотели определить %is_US_state?

12
ответ дан 27 November 2019 в 22:55
поделиться

См. также , Schwartzian преобразовывают для усовершенствованного использования карты.

18
ответ дан 27 November 2019 в 22:55
поделиться

map функция используется для преобразования списков. Это - в основном синтаксический сахар для замены определенных типов for[each] циклы. После того как Вы переносите голову вокруг этого, Вы будете видеть использование для него везде:

my @uppercase = map { uc } @lowercase;
my @hex       = map { sprintf "0x%x", $_ } @decimal;
my %hash      = map { $_ => 1 } @array;
sub join_csv { join(',', map {'"' . $_ . '"' } @_ }
21
ответ дан 27 November 2019 в 22:55
поделиться

В первую очередь, это - простой способ преобразовать массив: вместо высказывания, например.

my @raw_values = (...);
my @derived_values;
for my $value (@raw_values) {
    push (@derived_values, _derived_value($value));
}

можно сказать

my @raw_values = (...);
my @derived_values = map { _derived_value($_) } @raw_values;

Это также полезно для создания быстрой справочной таблицы: вместо, например.

my $sentence = "...";
my @stopwords = (...);
my @foundstopwords;
for my $word (split(/\s+/, $sentence)) {
    for my $stopword (@stopwords) {
       if ($word eq $stopword) {
           push (@foundstopwords, $word);
       }
    }
}

Вы могли сказать

my $sentence = "...";
my @stopwords = (...);
my %is_stopword = map { $_ => 1 } @stopwords;
my @foundstopwords = grep { $is_stopword{$_} } split(/\s+/, $sentence);

Также полезно, если Вы хотите получить один список от другого, но не должны особенно иметь временной переменной, загромождающей место, например, а не

my %params = ( username => '...', password => '...', action => $action );
my @parampairs;
for my $param (keys %params) {
    push (@parampairs, $param . '=' . CGI::escape($params{$param}));
}
my $url = $ENV{SCRIPT_NAME} . '?' . join('&amp;', @parampairs);

Вы говорите намного более простое

my %params = ( username => '...', password => '...', action => $action );
my $url = $ENV{SCRIPT_NAME} . '?'
    . join('&amp;', map { $_ . '=' . CGI::escape($params{$_}) } keys %params);

(Редактирование: зафиксированный недостающие "ключи %params" в той последней строке)

29
ответ дан 27 November 2019 в 22:55
поделиться

Функция карты является идеей от парадигмы функционального программирования. В функциональном программировании функции являются первоклассными объектами, означая, что они могут быть переданы как аргументы другим функциям. Карта является простым, но очень полезным примером этого. Это берет в качестве его аргументов функцию (позволяет, называют его f), и список l. f должна быть функция, берущая один аргумент, и карта просто применяется f к каждому элементу списка l. f может сделать то, в чем Вы нуждаетесь сделанный к каждому элементу: добавьте тот к каждому элементу, придайте каждому элементу квадратную форму, запишите каждый элемент в базу данных или откройте окно веб-браузера для каждого элемента, который, оказывается, допустимый URL.

преимущество использования map состоит в том, что оно приятно инкапсулирует итерацию по элементам списка. Все, что необходимо сделать, говорят, "делают f к каждому элементу, и это [до 118], чтобы решить, как лучше всего сделать это. Например map может быть реализован для разделения его работы среди нескольких потоков, и это было бы полностью очевидно для вызывающей стороны.

Примечание, это map нисколько не характерно для Perl. Это - стандартная техника, используемая функциональными языками. Это может даже быть реализовано в C, использующем указатели функции, или в C++ с помощью "функциональных объектов".

5
ответ дан 27 November 2019 в 22:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: