将2个哈希表转换为一个而不会丢失键的顺序

时间:2018-02-26 09:24:45

标签: perl

我正在尝试做一些我认为很简单的事情,但似乎我要么错过了一封信或其他什么,或者我只是不知道如何正确地做到这一点。 我有2个带有值的哈希表。 例如(用简单的代码编写,只是为了说明哈希!我知道语法在代码中的样子):

%hash1=>(key1,key2,key3)=>[value1,value2,value3]
%hash2=>(key4,key5,key6)=>[value4,value5,value6]

我想合并这两个,所以我将有一个哈希,这些键和&价值观(订单事宜)。

%hash3=> (key1,key2,key3,key4,key5,key6) =>[value1,value2,value3,value4,value5,value6]

我尝试使用Hash::Merge,但失败了。我试图切片哈希:

(@Hash1{ keys %Hash2 } = values %Hash2)

因为我认为它只会将其添加到列表的“底部”。它似乎不起作用。

我开始思考,它是在创建它们时添加它们,并且它们按此顺序创建: VALUE4,值5,值1,值2,value6,值3

所以可能,这就是它为什么这样做...但是......我想避免选择在完成之后循环遍历每个哈希,只是逐个添加...除此之外是否还有其他选项? (该脚本运行时间不到0.1秒,因此无论哪种方式都可以,但我希望代码看起来不错,并且正常工作。 感谢。

1 个答案:

答案 0 :(得分:5)

哈希键没有固定的顺序。要按特定顺序保留元素,您可以使用例如数组,或者像Tie::IxHashTie::Hash::Indexed这样的模块(如@daxim所建议,谢谢) - 但请参阅下面有关这些模块的内容

但是,我个人发现,在大多数情况下,使用其他模块而不是按照特定顺序保留哈希值,只需sort输出即可:

my %hash1 = (key1=>'value1', key2=>'value2', key3=>'value3');
my %hash2 = (key4=>'value4', key5=>'value5', key6=>'value6');
my %hash3 = (%hash1, %hash2);
for my $key (sort keys %hash3) {
    print "$key: $hash3{$key}\n";
}

输出:

key1: value1
key2: value2
key3: value3
key4: value4
key5: value5
key6: value6

另请参阅常见问题解答How do I sort a hash (optionally by value instead of key)?How can I always keep my hash sorted?

这是一个Tie::IxHash示例,输出与上面相同;请注意不需要sortTie::IxHash将保留将元素添加到哈希的顺序 - 请确保这是您想要的,因为它与排序相同输出上的键,如上所示 - 模块记住了插入顺序,而sort解决方案只对输出键进行排序,而不更改原始哈希中的任何内容。使用tie d哈希也会对性能产生影响。

use Tie::IxHash;
tie my %hash1, 'Tie::IxHash';
tie my %hash2, 'Tie::IxHash';
tie my %hash3, 'Tie::IxHash';
%hash1 = (key1=>'value1', key2=>'value2', key3=>'value3');
%hash2 = (key4=>'value4', key5=>'value5', key6=>'value6');
%hash3 = (%hash1, %hash2);
for my $key (keys %hash3) {
    print "$key: $hash3{$key}\n";
}