展平Perl的哈希数组

时间:2014-04-24 17:04:50

标签: perl

目前有这个演示代码:

use 5.012;
use Data::Dump;

my $AoH = [
    {a => "aval"},  #exactly only one key-value
    {b => "bval"},  #for each
    {c => "cval"},  #array element
];

dd $AoH;

my @arr = map { each $_ } @$AoH;
dd @arr;

它起作用并产生我想要的结果

[{ a => "aval" }, { b => "bval" }, { c => "cval" }]
("a", "aval", "b", "bval", "c", "cval")

问题是:map { each $_ }构造是正确的,还是可以用“另一种方式”来做到这一点?

2 个答案:

答案 0 :(得分:5)

只需取消引用hashrefs:

my $AoH = [
    {a => "aval"},  #exactly only one key-value
    {b => "bval"},  #for each
    {c => "cval"},  #array element
];

# Flatten the hash refs
my @arr = map { %$_ } @$AoH;

我建议不要在这种情况下使用each。来自perldoc

  

从Perl 5.14开始,each可以使用标量EXPR,它必须保持对未经处理的散列或数组的引用。该参数将自动解除引用。 each的这一方面被认为是高度实验性的。在未来的Perl版本中,确切的行为可能会发生变化。

答案 1 :(得分:0)

  

是正确的地图{每个$ _}构造,

不完全是。在您的具体情况下,它会做你想要的。但是,正如@ikegami所指出的,这会在你的代码中引入一个微妙的错误,做你做过两次的事情,你会看到问题所在。每个哈希都有一个内部迭代器,只有在你耗尽了这个哈希后才会重置这个迭代器,并再次读取它。 (它类似于feof()。)

此外,each $_仅在Perl 5.14或更高版本可用时,对于早期版本,您需要使用map { each %$_ }

但是,REAL问题是没有必要使用each,你可以使用map { %$_ },在列表上下文中,hash将返回由其键值对组成的列表。< / p>

  

或者可以用“另一种方式”来做到这一点吗?

同样可以,您可以使用foreachpush,如下所示:

push @arr, %$_ foreach @$AoH;

但是,这与您的方法基本相同。