Perl中的双哈希值

Lui*_* D. 3 perl hash

使用哈希时,Perl有一个非常方便的values关键字来处理哈希值.

假设我有一个双哈希,即像这样创建的东西:

my %dh = map { {$_->{id1}}{$_->{id2}} => $_ } @arr;
Run Code Online (Sandbox Code Playgroud)

然后values %dh返回一个哈希数组.要访问值,我需要这样的东西:

for my $key1 (keys %dh) {
    for my $val (values %{ $dh{$key1} }) {
        # stuff...
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来做到这一点,避免for循环?有点像values %{ values %dh }.

此外,抱歉语法不好,我对Perl很新.

Sob*_*que 5

您可以map再次使用它来提取它.不要有任何幻想 - 它仍然在循环.它可能更优雅:

for my $val ( map { values %$_ } values %dh ) {
    #do stuff
}
Run Code Online (Sandbox Code Playgroud)

这或多或少做了同样的事情 - 它正在使你的哈希变平 - 获取valuesfrom %dh- 这将是一个hash-refs列表 - 然后拉出values那些.(我认为应该这样做,但没有测试数据,我无法确定).

注意 - 返回订单values是未定义的,因此您将以随机顺序获取它们.如果您愿意,可以通过keys(也许sort)控制订购.

什么map是简单地评估代码块,并将结果作为列表返回.这就是为什么map { $_ => 1 } qw ( one two three )有效 - 它实际上返回了一对值,当你将它分配给哈希时,它被视为键值对.

use Data::Dumper;

my @stuff = map { $_ => 1 } qw ( one two three );
print Dumper \@stuff;
my %hash = map { $_ => 1 } qw ( one two three ); 
print Dumper \%hash;
Run Code Online (Sandbox Code Playgroud)

所以 - map这里返回2个值,你可以这样写:

my @stuff = map { $_,  1 } qw ( one two three );
Run Code Online (Sandbox Code Playgroud)

因为当然,=>它实际上只是一个逗号(引用一些额外的功能).

因此,在对数组进行解引用时,您可以执行相同的操作 - values从中返回每个元素的值列表map.

为清楚起见:

use Data::Dumper;
my @stuff = ( [ 1, 2, 3 ], [4, 5, 6], [7, 8, 9] );
print Dumper \@stuff;
my @newstuff = map { @$_ } @stuff; 
print Dumper \@newstuff;
Run Code Online (Sandbox Code Playgroud)

基本上做同样的事情 - 遍历每个哈希引用@stuff(因为这是多维数组的实现方式perl),然后"解包"它们,返回结果.

  • ..牛肉在这里,您可以从传递给地图的代码块中返回多个值,它们将从地图展平为一个值流. (2认同)