2010-09-15 13 views
27

Mam linie kodu z dwoma dużymi tablicami (więc nie mogę po prostu zapisać go w hasz), które chcę połączyć z hash.Jak mogę przypisać dwie tablice do skrótu w Perlu?

Na przykład $array1[0] staje się kluczem, a $array2[0] staje się wartością i tak dalej do $array1[150], $array2[150].

Jakieś pomysły, jak to zrobić?

Odpowiedz

56

Można to zrobić w jednym przypisania:

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

Jest to wspólny idiom. Od perldoc perldata on slices:

Jeśli jesteś zagubiony, dlaczego używasz „@” tam na plasterek hash zamiast z „%”, pomyśl o tym w ten sposób. Klamra (kwadratowa lub kręcona) decyduje o tym, czy jest to tablica, czy też analizowany jest hasz o tablicy lub . Z drugiej strony główny symbol ("$" lub "@") w tablicy lub krzyżyku wskazuje, czy otrzymujesz pojedynczą wartość (skalar) lub liczbę mnogą (lista).

Kiedy widzę jeden z nich widzę wyobrażenie zamek błyskawiczny ...

+0

Ciekawostki: nie jesteś jedyny. W python znajduje się wbudowana funkcja do konwersji dwóch równoległych tablic do pojedynczej tablicy dwuelementowych krotek i nazywa się ... zip()! http://docs.python.org/library/functions.html#zip :) –

+8

Perl ma 'zip' w [List :: MoreUtils] (http://search.cpan.org/dist/List-MoreUtils) . Istnieje również [jest elegancki zip do przeplatania dwóch list w Perlu] (http://stackoverflow.com/q/38345/8817). –

14

Martin Clayton ma best answer for your general question, umieścić tam również ciekawą nowością w Perl 5.12. Możesz użyć each on an array, dzięki czemu możesz łatwo iterować przez równoległe tablice. Jest to przydatne, gdy chcesz manipulować wartości przed ich użyciem:

while(my($index, $value) = each @array1) { 
     ...; # maybe do something to $value 
     $hash{ $value } = $array2[$index]; 
     } 
+0

http://news.perlfoundation.org/2010/09/perl-5122-released.html –

2

(. Próbowałem delegowania to jako komentarz do odpowiedzi Brian, ale nie mógł uzyskać prawo formatowania)

Musisz zachowaj ostrożność, aby uniknąć zagnieżdżonych zastosowań each. each działa na "globalnym" iteratorze w tablicy. Po osiągnięciu końca zwraca wartość false, a następnie resetuje pozycję do początku. Tak więc poniższy kod powoduje nieskończoną pętlę.

Dzięki RJBS za jego talk at YAPC::NA, gdzie wskazał na globalny charakter wbudowanego iteratora.

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"; 
     } 
} 
+1

Cóż, musisz unikać wszelkiego rodzaju rzeczy, które mogą zepsuć twój program. Wszystko to jest udokumentowane we wpisie perlfunc dla każdego z nich. –

+0

@ brian. Nie narzekałem na twoją odpowiedź, tylko chciałem zapobiec trudnym do wytłumaczenia błędom. ;) Z perspektywy czasu prawdopodobnie podałem zbyt wiele informacji, biorąc pod uwagę to pytanie. –

3
use List::MoreUtils qw(zip); 

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

my @b = 1 .. 5; 

my %hash = zip @a, @b; 
Powiązane problemy