除非你使用类似Tie::IxHash它看起来像一个哈希值,但实际上不是(这意味着它没有一个哈希的相同的性能特征),在其中你得到的元素是要顺序难以预测[1]。因此,通过一些外部手段(如sort
)来控制散列元素的访问顺序是一种常见的做法。
for my $key (sort keys(%hash)) {
...
}
散列是链表的阵列。散列函数将该键转换为一个数字,该数字用作存储该值的数组元素(“存储区”)的索引。链表处理多个密钥散列到同一个索引(“碰撞”)的情况。
所以元素自然按索引排序,也就是说通过它们的键的散列。对于偶然的观察者来说,这个命令似乎是随机的。
但是出于安全原因,Perl会对此自然顺序进行更改。
当存储桶开始接收大部分散列元素时,由于查找成为链接列表的搜索,散列表现会降低。恶意行为者可以通过故意提供可触发退化事件的值来对系统进行DOS操作。
Perl会采取措施避免该情况,并在散列因意外或意外而变质时修复散列。我对所有的细节都不熟悉,而且他们在一年中都发生了变化。它们涉及随机化散列算法并随机化元素返回的顺序。
这使得订单甚至出现更随机,
一个例外:在keys
,value
和each
回报元素始终是一个给定的哈希值相同,只要你不顺序不改变散列。
$ perl -E'
@h{ "a".."i" } = 0..8;
say map { $h{$_} } keys %h;
say map { $h{$_} } keys %h;
say values %h;
$h{j} = 9;
say map { $h{$_} } keys %h;
say map { $h{$_} } keys %h;
say values %h;
'
580734216
580734216
580734216
0985216734
0985216734
0985216734
将意味着它是安全的,请执行下列操作:
# Add the elements of %hash1 to %hash2.
@hash2{ keys(%hash1) } = values(%hash1);
@serenesat不,散列没有订单,直到你强加在他们身上的外部的顺序关系。数组有秩序,因为它们的键是定义在其上的自然顺序的整数,而不考虑它们的使用方式。即使如此,数组的自然顺序可能并不是您想要强加给数据结构的顺序,这就是为什么存在“排序”功能的原因。 –
是的。删除我的评论。 – serenesat