【问题标题】:Double hash values in PerlPerl 中的双重哈希值
【发布时间】:2016-05-23 18:11:55
【问题描述】:

当使用散列时,Perl 有一个非常方便的values 关键字来仅处理散列的值。

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

my %dh = map { {$_->{id1}}{$_->{id2}} => $_ } @arr;

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

for my $key1 (keys %dh) {
    for my $val (values %{ $dh{$key1} }) {
        # stuff...
    }
}

有没有更好的方法来避免for 循环?像values %{ values %dh } 这样的东西。

另外,很抱歉语法不好,我对 Perl 很陌生。

【问题讨论】:

  • map 和 keys 我猜,但我现在没有足够的时间来构建测试用例。

标签: perl hash


【解决方案1】:

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

for my $val ( map { values %$_ } values %dh ) {
    #do stuff
}

这或多或少是在做同样的事情——它使你的哈希变平——从%dh 获取values——这将是一个哈希引用列表——然后将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;

所以 - map 在这里返回 2 个值,您可以写成:

my @stuff = map { $_,  1 } qw ( one two three );

因为当然,=> 实际上只是一个逗号(在引用周围有一些额外的功能)。

因此,当对数组进行取消引用时,您也可以这样做——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;

本质上是在做同样的事情——遍历@stuff 中的每个哈希引用(因为这就是perl 中实现多维数组的方式),然后“解包”它们,返回结果。

【讨论】:

  • .. 牛肉在这里,您可以从传递给 map 的代码块中返回多个值,它们将被展平为来自 map 的一个值流。
猜你喜欢
  • 1970-01-01
  • 2010-10-20
  • 2021-02-13
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
  • 2014-03-24
相关资源
最近更新 更多