使用哈希时,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很新.
您可以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),然后"解包"它们,返回结果.