假设我有一个值数组,然后是键(与散列的赋值相反):
use strict;
use warnings;
use Data::Dump;
my @arr = qw(1 one 2 two 3 three 4 four 1 uno 2 dos 3 tres 4 cuatro);
my %hash = @arr;
dd \%hash;
打印
{ 1 => "uno", 2 => "dos", 3 => "tres", 4 => "cuatro" }
显然,构造散列时会删除重复的键。
如何反转用于构造散列的值对的顺序?
我知道我可以写一个C风格循环:
for(my $i=1; $i<=$#arr; $i=$i+2){
$hash{$arr[$i]}=$arr[$i-1];
}
dd \%hash;
# { cuatro => 4, dos => 2, four => 4, one => 1, three => 3, tres => 3, two => 2, uno => 1 }
但这似乎有点笨拙。我正在寻找一些更加惯用的Perl。
在Python中,我只会做dict(zip(arr[1::2], arr[0::2]))
答案 0 :(得分:8)
答案 1 :(得分:4)
TLP有正确的答案,但避免删除重复密钥的另一种方法是使用数组哈希。我假设这是你首先反转数组的原因。
use strict;
use warnings;
use Data::Dump;
my @arr = qw(1 one 2 two 3 three 4 four 1 uno 2 dos 3 tres 4 cuatro);
my %hash;
push @{ $hash{$arr[$_]} }, $arr[$_ + 1] for grep { not $_ % 2 } 0 .. $#arr;
dd \%hash;
{
1 => ["one", "uno"],
2 => ["two", "dos"],
3 => ["three", "tres"],
4 => ["four", "cuatro"],
}
正如评论中ikegami所建议的那样,您可以查看CPAN上提供的List::Pairwise模块,以获得更易读的解决方案:
use strict;
use warnings;
use Data::Dump;
use List::Pairwise qw( mapp );
my @arr = qw(1 one 2 two 3 three 4 four 1 uno 2 dos 3 tres 4 cuatro);
my %hash;
mapp { push @{ $hash{$a} }, $b } @arr;
dd \%hash;
答案 2 :(得分:0)
如果您的值数组,键已准备好进入哈希值,则TLP具有right answer。
也就是说,如果你想在进入哈希之前以任何方式处理密钥或值,我发现这是我使用的东西:
while (my ($v, $k)=(shift @arr, shift @arr)) {
last unless defined $k;
# xform $k or $v in someway, like $k=~s/\s*$//; to strip trailing whitespace...
$hash{$k}=$v;
}
(注意 - 对数组@arr
具有破坏性。如果您想将@arr
用于其他内容,请先复制它。)