10

I love hash slices and use them frequently:

my %h;
@h{@keys}=@vals;

Works brilliantly! But 2 things have always vexed me.

First, is it possible to combine the 2 lines above into a single line of code? It would be nice to declare the hash and populate it all at once.

Second, is it possible to slice an existing anonymous hash... something like:

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

3 回答 3

9
  • 第一个问题:

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

    或者

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

    如果它是...NAME...一个哈希,它是...{ $href }...一个哈希引用,所以

    my @slice = @hash{@fields};
    

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

    如果引用表达式是变量,则花括号是可选的。

    my @slice = @$anonh{@fields};
    
于 2013-07-24T15:22:06.180 回答
8

对于您的第一个问题,只需一行代码即可:

@$_{@keys}=@vals for \my %h;

或者

map @$_{@keys}=@vals, \my %h;

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

任何一个版本都声明了变量并立即获取对它的引用和引用的别名$_,以便哈希引用可以在切片中使用。这使您可以在现有范围内声明变量;@{ \my %h }{@keys} = @vals;也“有效”,但有一个不幸的缺点,就是将范围限定%h在哈希片中的那个小块上。

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

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

或者你的意思是:

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

但是 @slice/$slice 有一个值的副本。要获取哈希值的别名数组,您可以执行以下操作:

my $slice = sub { \@_ }->( @$anonh{@fields} );
于 2013-07-24T15:06:57.167 回答
3

哈希切片语法是

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

当您对哈希引用进行切片时,请将其括在花括号中,这样它就不会作为数组被取消引用。这给了你:

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

对于哈希参考$anonh

于 2013-07-24T15:03:01.807 回答