我有以下脚本
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
我该怎么做?
答案 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安装它们(例如,使用cpan
或cpanm
命令)。
答案 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
。或者数组。