lut*_*act 4 sorting perl hash data-structures perl-data-structures
我想使用相同的键构建多个哈希,并且当我打印它们时键要具有相同的顺序.因此,在下面的例子中,密钥$hash1和$hash2应始终具有相同的顺序,但应该没有必要创建哈希时保留这个顺序.
use Data::Dumper;
my $hash1 = {
keyc => 2,
key1 => 1,
keya => 3,
keyb => 4,
};
my $hash2 = {
keyc => 2,
key1 => 1,
keya => 3,
keyb => 4,
};
print Dumper $hash1, $hash2;
Run Code Online (Sandbox Code Playgroud)
但输出如下:
$VAR1 = {
'key1' => 1,
'keyc' => 2,
'keyb' => 4,
'keya' => 3
};
$VAR2 = {
'keyb' => 4,
'keya' => 3,
'keyc' => 2,
'key1' => 1
};
Run Code Online (Sandbox Code Playgroud)
即哈希有不同的意外顺序.我的perl出了什么问题?
我的perl版本是:
This is perl 5, version 18, subversion 2 (v5.18.2) built for darwin-thread-multi-2level
(with 2 registered patches, see perl -V for more detail)
Run Code Online (Sandbox Code Playgroud)
注意:我知道perl哈希的键是未排序的顺序.我希望他们有相同的订单,但不应该有排序的订单.我希望如果再次运行代码,我可以获得相同的打印输出.
根据答案的建议,我设置了两个环境变量:
PERL_HASH_SEED=0x00 PERL_PERTURB_KEYS=0
然后,当我重复运行代码时,我可以获得相同的输出.
G. *_*ito 12
在打印哈希时,有几个不同的顺序概念是相关的:"插入顺序","排序顺序"和"随机".有关可以控制此行为的方法以及默认情况下使用散列随机化的原因的讨论,请参阅文档的" 环境"部分perlrun.
在perl中至少十年的哈希值并没有保证关键顺序.最近,散列随机化已经成为一般安全"强化"努力的一部分.哈希有很好的理由随机化.有关更多详细信息,请参阅perlsec算法复杂性攻击的讨论.您将在Perl安全文档中注意到已添加了进一步的增强功能perl-5.18- 如果您看到与先前版本相比的不同行为,则可能是由于这些最新更改.
除了以确定的方式显式排序哈希键之外,还可以采用其他方法来排序哈希:Hash::Ordered就是一个例子.该Hash::Ordered文档很好地讨论了许多其他模块的优缺点.
哈希是一个按键值对排列的标量的" 无序篮子 "; 数组是标量的" 有序序列 " [ 1 ]." 切片 "是同时访问"列表,数组或散列的几个元素"的方式.切片使用@sigil,因为操作返回多个值的列表 - 并且@我们得到"有序序列".结果是在散列上强加一种"顺序"的一种方法是使用切片来访问它:
# We want alphabetical disorder ...
my %hashed = ( 1 => "z", 2 => "x", 3 => "y" );
for my $key ( keys %hashed ) { print $hashed{$key} } ;
__END__
zyx
Run Code Online (Sandbox Code Playgroud)
我们想要" zxy"不是" zyx".要在这个哈希上强加我们的任意版本的顺序,我们首先需要认识到这里的罪魁祸首是以keys %hashed随机顺序返回密钥.解决方案是sortccurse的密钥,在这个人为的例子中,我们将它们存储起来@sort_order并用它来"切割"我们想要的哈希,我们想要的方式:
my @sort_order = sort keys %hashed ;
print @hashed{@sort_order} ;
__END__
zxy
Run Code Online (Sandbox Code Playgroud)
田田!当您想要在散列中存储键和值但以有序方式访问该数据时,切片会很有用.@当你想要切片哈希时记住" "; 如perldata所说的那样:"你用的'@'......(因为)你正在回来......一个列表...一个散列片".列表是有序的.
[ 1 ]散列为"无序篮子"和数组为"有序序列"的定义来自Mike Friedman(FRIEDO)关于Perl中阵列与列表的优秀文章.
进一步的参考
perlfaq-q如何始终保持哈希排序?