以正确的顺序散列键和值
Posted
技术标签:
【中文标题】以正确的顺序散列键和值【英文标题】:Hash keys and values in the right order 【发布时间】:2018-06-26 12:58:18 【问题描述】:我已经多次看到下面这段代码将一个哈希连接到另一个哈希
%hash1 = ('one' => "uno");
%hash2 = ('two' => "dos", 'three' => "tres");
@hash1keys %hash2 = values %hash2;
我认为每次调用“values”或“keys”函数时,它们的输出顺序都是随机的。如果是这样,上面的语句如何在两边以正确的顺序获取键和值?
换句话说,为什么在合并两个哈希后没有机会在 %hash1 中获得 'two' => 'tres'? Perl 是否足够聪明,知道如果在同一行调用“键”和“值”,那么键和值必须以相同的顺序给出?
【问题讨论】:
简化:哈希算法的工作方式是在程序的相同执行期间,给定哈希中的项目的顺序是随机的,但保证相同。如果数据结构发生变化,顺序可能会发生变化。第二次调用程序时,不保证是一样的。 【参考方案1】:见perldoc -f keys
只要未修改给定的哈希值,您就可以依赖键、值和每一个重复返回彼此相同的顺序。
【讨论】:
【参考方案2】:哈希是一个链表数组。散列函数将键转换为一个数字,该数字用作存储值的数组元素(“桶”)的索引。多个键可以散列到同一个索引(“冲突”),这种情况由链表处理。
keys
、values
和each
使用的迭代器以与它们在哈希中的位置一致的顺序返回元素。我想它会遍历第一个桶中的链表,然后遍历第二个桶中的链表,等等。关键是它不会随机化它遍历散列元素的顺序。这就是文档保证以下内容的原因:
只要未修改给定的哈希值,您就可以依赖键、值和每一个重复返回彼此相同的顺序。
什么是“随机”[1] 是密钥将散列到哪个桶号。每个散列都有一个随机的秘密数字,它会扰乱散列函数。这会导致散列中元素的顺序对于每个散列和程序的每次运行都不同。[2]
向散列添加元素会导致桶数增加,并可能导致触发秘密数改变(如果其中一个链表变得异常长)。这两者都会改变该哈希中元素的顺序。
$ perl -le'
my %h1 = map $_ => 1 "a".."j";
my %h2 = map $_ => 1 "a".."j";
print keys(%$_) for \%h1, \%h1, \%h2, \%h2;
'
hjfeadbigc
hjfeadbigc
bdgcifjhae
bdgcifjhae
$ perl -le'
my %h1 = map $_ => 1 "a".."j";
my %h2 = map $_ => 1 "a".."j";
print keys(%$_) for \%h1, \%h1, \%h2, \%h2;
'
dcahigjbfe
dcahigjbfe
gihacdefbj
gihacdefbj
-
这不是完全随机的。如果在哈希中插入两个元素,则迭代器在第一个元素之后返回第二个元素的几率超过 50%。
在旧版本的 Perl 中,事情并不那么随机。
【讨论】:
以上是关于以正确的顺序散列键和值的主要内容,如果未能解决你的问题,请参考以下文章