Perl技术求助:按创建顺序获取哈希数组值失败
解决Perl哈希数组中内层哈希的顺序问题
你的问题出在只给外层哈希绑定了有序哈希,内层的嵌套哈希并没有被处理——虽然你给%idAlignment用了Tie::IxHash::Easy,但当你创建$idAlignment{1}{r1}和$idAlignment{1}{t1}时,$idAlignment{1}对应的是一个默认的普通Perl哈希,普通哈希的keys遍历是无序的,这就是为什么输出顺序和你创建键的顺序不一致。
这里有两种简单的解决方案:
方案1:手动绑定内层哈希
你可以显式地给每个内层哈希绑定Tie::IxHash::Easy,确保它也保持键的插入顺序:
use strict; use warnings; use Tie::IxHash::Easy; # 绑定外层哈希 tie my %idAlignment, 'Tie::IxHash::Easy'; # 创建并绑定内层哈希,确保r1和t1的顺序被保留 tie my %inner_aln, 'Tie::IxHash::Easy'; @{$inner_aln{r1}} = qw/4032.82 4145.04 4519.05 4527.46 5144.13/; @{$inner_aln{t1}} = qw/4032.86 4144.92 4519.11 - -/; # 将内层哈希引用赋值给外层哈希 $idAlignment{1} = \%inner_aln; printAlnCols($idAlignment{1}, 0); sub printAlnCols { my ($aln_ref, $col_index) = @_; # 直接遍历绑定后的哈希引用,不要转成普通哈希 foreach my $key (keys %{$aln_ref}) { print $aln_ref->{$key}[$col_index], "\n"; } }
方案2:用Tie::Autotie自动绑定所有嵌套哈希
如果你有很多层嵌套哈希,手动绑定太麻烦,可以用Tie::Autotie让Perl自动给所有新建的哈希绑定Tie::IxHash::Easy,这样不管外层还是内层哈希都会保持顺序:
use strict; use warnings; use Tie::IxHash::Easy; use Tie::Autotie; # 关键:在创建任何哈希之前,设置自动绑定所有HASH类型 autotie 'HASH' => 'Tie::IxHash::Easy'; # 现在所有新建的哈希(包括内层的)都会自动是有序哈希 my %idAlignment; @{$idAlignment{1}{r1}} = qw/4032.82 4145.04 4519.05 4527.46 5144.13/; @{$idAlignment{1}{t1}} = qw/4032.86 4144.92 4519.11 - -/; printAlnCols($idAlignment{1}, 0); sub printAlnCols { my ($aln_ref, $col_index) = @_; foreach my $key (keys %{$aln_ref}) { print $aln_ref->{$key}[$col_index], "\n"; } }
额外注意点
- 不管用哪种方案,在
printAlnCols里不要把哈希引用转成普通哈希(比如my %Aln = %{$alnRef}),转成普通哈希后会丢失有序绑定的特性,变回无序遍历。 - 使用
Tie::Autotie时,一定要在创建任何哈希之前调用autotie,否则之前创建的哈希不会被绑定。
内容的提问来源于stack exchange,提问作者The August
相关产品推荐
相关产品推荐

