perl – 为什么哈希键在打印时有不同的顺序?

前端之家收集整理的这篇文章主要介绍了perl – 为什么哈希键在打印时有不同的顺序?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想使用相同的键构建多个哈希,并且当我打印它们时键要具有相同的顺序.因此,在下面的示例中,$hash1和$hash2的键应始终具有相同的顺序,但在创建哈希时不应该保持该顺序.

use Data::Dumper;

my $hash1 = {
  keyc => 2,key1 => 1,keya => 3,keyb => 4,};

my $hash2 = {
  keyc => 2,};

print Dumper $hash1,$hash2;

输出如下:

$VAR1 = {
          'key1' => 1,'keyc' => 2,'keyb' => 4,'keya' => 3
        };
$VAR2 = {
          'keyb' => 4,'keya' => 3,'key1' => 1
        };

即哈希有不同的意外顺序.我的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)

注意:我知道perl哈希的键是未排序的顺序.我希望他们有相同的订单,但不应该有排序的订单.我希望如果再次运行代码,我可以获得相同的打印输出.

根据答案的建议,我设置了两个环境变量:

PERL_HASH_SEED = 0x00 PERL_PERTURB_KEYS = 0

然后,当我重复运行代码时,我可以获得相同的输出.

解决方法

在打印哈希时,有几个不同的顺序概念是相关的:“插入顺序”,“排序顺序”和“随机”.有关可以控制此行为的方法以及默认使用散列随机化的原因的讨论,请参阅 ENVIRONMENT section of the perlrun文档.

在perl中至少十年的哈希值并没有保证关键顺序.最近,散列随机化已经成为一般安全“强化”努力的一部分.哈希有很好的理由随​​机化.有关详细信息,请参阅perlsec discussion of algorithmic complexity attacks.您将在Perl安全文档中注意到perl-5.18中添加了进一步的增强功能 – 如果您看到与先前版本相比的不同行为,则可能是由于这些最新更改.

除了以确定的方式明确表达sorting your hash keys之外,您还可以采用其他方法来排序哈希:Hash::Ordered就是一个例子. Hash :: Ordered文档很好地讨论了许多其他模块的优缺点.

哈希是一个按键值对排列的标量的“无序篮子”;数组是标量的“有序序列”[1]. “slice”是同时访问“列表,数组或散列的几个元素”的方式.切片使用@sigil,因为操作返回多个值的列表 – 并且使用@我们得到“有序序列”.结果是在散列上强加一种“顺序”的一种方法是使用切片来访问它:

# We want alphabetical disorder ...
my %hashed = ( 1 => "z",2 => "x",3 => "y" );
for my $key ( keys %hashed ) { print $hashed{$key} } ;
__END__    
zyx

我们想要“zxy”而不是“zyx”.要在这个哈希上强加我们的任意版本的顺序,我们首先需要认识到这里的罪魁祸首是密钥%哈希,它以随机顺序返回密钥.解决方案是对ccurse的键进行排序,在这个人为的例子中,我们将它们存储在@sort_order中,然后用它来“切割”我们想要的哈希值,我们想要的方式:

my @sort_order = sort keys %hashed ;
print @hashed{@sort_order} ;
__END__
zxy

田田!当您想要在散列中存储键和值但以有序方式访问该数据时,切片会很有用.当你想要切片哈希时,请记住“@”;正如perldata所说的那样:“你在哈希切片上使用’@’… … [因为]你回来了…一个列表”.列表是有序的.

[1]散列为“无序篮子”和数组为“有序序列”的定义来自Mike Friedman(FRIEDO)于Arrays vs. Lists in Perl的优秀文章.

进一步的参考

>比照perlfaq -q How can I always keep my hash sorted?
>除了创建一些非常有用的CPAN模块之外,GARU(Breno de Oliveira)于an excellent article on hash ordering发布,它完全涵盖了最近的Perl开发和散列随机化问题.
>有关使用哈希切片可以做的整洁事物的更高级示例,请参阅Vince Veselosky的文章Hash slices can replace loops.

猜你在找的Perl相关文章