Как я могу назначить два массива для хэша в Perl? - PullRequest
31 голосов
/ 15 сентября 2010

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

Например, $array1[0] становится ключом, а $array2[0] становится значением и так далее до $array1[150], $array2[150].

Есть идеи, как мне это сделать?

Ответы [ 4 ]

65 голосов
/ 15 сентября 2010

Вы можете сделать это в одном задании:

my %hash;
@hash{@array1} = @array2;

Это обычная идиома.Начиная с perldoc perldata на слайсах :

Если вы не уверены, почему вы используете «@» в срезе хеша вместо «%», подумайте об этом какэтот.Тип скобок (квадратный или фигурный) определяет, будет ли это массив или хеш, на который нужно посмотреть.С другой стороны, начальный символ ('$' или '@') в массиве или хэше указывает, возвращаете ли вы единственное значение (скаляр) или множественное число (список).

Когда я вижу один из них, я вижу мысленный образ молнии ...

16 голосов
/ 15 сентября 2010

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

 while( my( $index, $value ) = each @array1 ) {
      ...; # maybe do something to $value
      $hash{ $value } = $array2[$index];
      }
4 голосов
/ 16 сентября 2010
use List::MoreUtils qw( zip );

my @a = 'A' .. 'E';

my @b = 1 .. 5;

my %hash = zip @a, @b;
3 голосов
/ 15 сентября 2010

(Я пытался опубликовать это как комментарий к ответу Брайана, но не смог правильно отформатировать.)

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

Спасибо RJBS за его выступление на YAPC :: NA , где он указал на глобальную природу встроенного итератора.

use strict;
use warnings;

my @array = 'A' .. 'J' ;

while ( my ($index, $value) = each @array){
        print "printing ($index, $value) from outer loop\n";

        while ( my ($index_in, $value_in) = each @array){
                print "printing ($index_in, $value_in) from inner loop\n";
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...