将数组转换中的键,值的顺序反转为哈希

时间:2014-09-08 16:49:17

标签: arrays perl hash

假设我有一个值数组,然后是键(与散列的赋值相反):

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]))

3 个答案:

答案 0 :(得分:8)

使用reverse

my %hash = reverse @arr;

Perl中的内置函数列表位于perldoc perlfunc

答案 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用于其他内容,请先复制它。)