按插入顺序打印哈希的内容

时间:2017-03-23 17:46:38

标签: perl sorting hash

我有以下脚本

my %hash = (
             'ev2'  => 'aaaa',
             'ev1' => 'bbbb'
           );   

for my $key (sort keys %hash) {
   print $key , '-' , $hash{$key},  "\n";
} 

打印

ev1 - bbbb
ev2 - aaaa

我想按照添加到哈希的顺序打印元素。

ev2 - aaaa  
ev1 - bbbb

我该怎么做?

3 个答案:

答案 0 :(得分:3)

不保留用于初始化哈希变量的列表中键/值对的顺序;在填充哈希变量时,该排序早已消失。

要保留密钥最初添加到哈希的顺序 - 包括用于初始化密钥的任何列表的顺序 - 您可以使用CPAN模块Hash::Ordered

它有一个tie接口,因此您可以使用Hash::Ordered对象,就像它是普通哈希一样。请注意,如果他们只是简单的话,您就不需要在=>左侧引用密钥:

use Hash::Ordered;

tie my %hash, Hash::Ordered => (
             ev2 => 'aaaa',
             ev1 => 'bbbb'
           );

while (my ($key, $value) = each %hash) {
  print "$key - $value\n";
}

输出:

ev2 - aaaa
ev1 - bbbb

您也可以像原始代码一样进行循环,只需要sort

for my $key (keys %hash) {
  print "$key - $hash{$key}\n";
}

但是使用each会为每个项目保存哈希查找,并以与keys相同的顺序返回它们。

@duskwuff先建议Hash::Ordered;我刚刚提供了一些示例代码。 @ikegami建议使用较旧的模块Tie::IxHash。两者都是为此目的而工作,并且都不是Perl的标准;您需要从CPAN安装它们(例如,使用cpancpanm命令)。

答案 1 :(得分:1)

哈希不会记录添加元素的顺序,因此您只需使用哈希就无法实现所需。

您可以使用Tie::IxHash提供类似哈希的内容,但会保留广告订单。

use Tie::IxHash qw( );

tie my %hash, Tie::IxHash => (
    ev2 => 'aaaa',
    ev1 => 'bbbb',
);   

for my $key ( keys(%hash) ) {
    my $val = $hash{$key};
    ...
}

使用Tie :: IxHash或类似模块会有性能损失。

如果您不需要访问任意元素,那么简单地使用数组就会快得多。

use List::Util qw( pairs );    # 1.29+

my @pairs = (
    ev2 => 'aaaa',
    ev1 => 'bbbb',
);   

for (pairs(@pairs)) {
    my ($key, $val) = @$_;
    ...
}

for (my $i=0; $i<@pairs; ) {
    my $key = $pairs[$i++];
    my $val = $pairs[$i++];
    ...
}

答案 2 :(得分:1)

你不能确切地说。哈希没有&#34;自然&#34; order - 不记录元素的分配顺序。

如果您确实需要有序哈希,请使用Hash::Ordered。或者数组。