2013-07-24 15 views
9

Kocham hash plasterki i używać ich często:Anonimowe plasterki Hash - składnia?

my %h; 
@h{@keys}[email protected]; 

Działa świetnie! Ale dwie rzeczy zawsze mnie dręczyły.

Po pierwsze, czy możliwe jest połączenie dwóch linii powyżej w pojedynczą linię kodu? Byłoby miło zadeklarować hash i zaludnić wszystko naraz.

Po drugie, jest to możliwe do krojenia istniejący anonimowy hash ... coś jak:

my $slice=$anonh->{@fields} 

Odpowiedz

8

Na pierwsze pytanie, to zrobić w jednej linii kodu:

@$_{@keys}[email protected] for \my %h; 

lub

map @$_{@keys}[email protected], \my %h; 

ale tego nie zrobił; to mylący sposób, aby to napisać.

Każda z wersji deklaruje zmienną i natychmiast pobiera odwołanie do niej i przypisuje ją do referencji, tak aby odwołanie do skrótu mogło zostać użyte w wycinku. Pozwala to zadeklarować zmienną w istniejącym zakresie; @{ \my %h }{@keys} = @vals; również "działa", ale ma niefortunną wadę z zakresu %h do tego małego bloku w skrawku skrótu.

Dla twojego drugiego pytania, jak pokazano powyżej, plasterki mogą być używane na referencjach hash; zobacz http://perlmonks.org/?node=References+quick+reference dla niektórych łatwych do zapamiętania zasad.

my @slice = @$anonh{@fields}; 

czy może masz na myśli:

my $slice = [ @$anonh{@fields} ]; 

ale @ plaster/$ kawałek jest kopią wartości.Aby uzyskać tablicę aliasów do wartości hash, można zrobić:

my $slice = sub { \@_ }->(@$anonh{@fields}); 
+0

Te jednolinijki są o wiele mniej obrzydliwe niż '$ h -> {$ a} = $ b while ($ a, $ b) = ($ ea // = Lista :: MoreUtils :: each_array (klawisze @, wartości @)) ->() 'Nad tym pracowałem. – mob

+0

@mob: '% h = Algorytm :: Pętle :: MapCarE {@_} \ @keys, \ @values;' – ysth

+0

Tak wiele dobrych odpowiedzi ... zaakceptował ten, ponieważ był pierwszy. :-) – mswanberg

3

składnia plaster Hash jest

@ <hash-name-or-hash-ref> { LIST } 

Podczas krojenia odniesienie skrótu, należy ująć ją w nawiasy klamrowe, dzięki czemu nie zostanie odwołane jako tablica. To daje:

my @values = @{$anonh}{@fields} 

za skrót hasłowy $anonh.

8
  • Pierwsze pytanie:

    my %h = map { $keys[$_] => $vals[$_] } 0..$#keys; 
    

    lub

    use List::MoreUtils qw(mesh); 
    
    my %h = mesh @keys, @vals; 
    
  • Drugie pytanie:

    Jeśli jest to ...NAME... do mieszania, to ...{ $href }... o sygn hash, więc

    my @slice = @hash{@fields}; 
    

    jest

    my @slice = @{ $anonh }{@fields}; 
    

    nawiasów klamrowych są opcjonalne, jeśli wyrażenie odniesienia jest zmienna.

    my @slice = @$anonh{@fields};