2013-07-24 41 views
9

我爱散列片段,并经常使用它们:出色匿名哈希片 - 语法?

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

作品!但有两件事一直让我烦恼。

首先,是否有可能将上面的两行代码合并成一行代码?这将是很好的声明哈希和一次填充它。

其次,是有可能切片现有的匿名散列......是这样的:

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

回答

8

关于第一个问题,做到在一个单一的代码行:

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

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

,但我不会那样做的;写它是一种令人困惑的方式。

两个版本都声明该变量并立即引用该引用,并将别名$_引用到引用,以便可以在片中使用散列引用。这使您可以在现有范围内声明该变量; @{ \my %h }{@keys} = @vals;也“有效”,但具有将%h作用于散列片中的那个小块的不幸缺点。

对于第二个问题,如上所示,切片可用于哈希引用;请参阅http://perlmonks.org/?node=References+quick+reference,了解一些易于记忆的规则。

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

或者你的意思是:

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

但@片/ $切片存在的值的副本。为了获得别名的数组的哈希值,你可以这样做:

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

那些单行者比$ h - > {$ a} = $ b要少得多,而($ a,$ b)=($ ea // = List :: MoreUtils :: each_array (@ keys,@ values)) - >()'我正在研究。 – mob

+0

@mob:'%h = Algorithm :: Loops :: MapCarE {@_} \ @keys,\ @values;' – ysth

+0

很多好的答案......接受这个答案是因为它是第一个。 :-) – mswanberg

3

散列切片语法是

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

当你切片散列引用,将其括在大括号,所以它不会像数组一样被解引用。这给你:

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

为散列参考$anonh

8
  • 第一个问题:

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

    use List::MoreUtils qw(mesh); 
    
    my %h = mesh @keys, @vals; 
    
  • 第二个问题:

    如果是...NAME...为散列,这是为...{ $href }...哈希REF,所以

    my @slice = @hash{@fields}; 
    

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

    的花括号是可选的,如果参考表达是一个变量。

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