加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间:2020-12-15 23:29:28 所属栏目:大数据 来源:网络整理
导读:我想使用相同的键构建多个哈希,并且当我打印它们时键要具有相同的顺序.因此,在下面的示例中,$hash1和$hash2的键应始终具有相同的顺序,但在创建哈希时不应该保持该顺序. use Data::Dumper;my $hash1 = { keyc = 2,key1 = 1,keya = 3,keyb = 4,};my $hash2 = {
我想使用相同的键构建多个哈希,并且当我打印它们时键要具有相同的顺序.因此,在下面的示例中,$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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读