如果您在标量上下文中评估哈希,您会得到什么?

时间:2011-09-15 07:39:59

标签: perl

请考虑以下代码段:

use strict;
use warnings;

my %a = ( a => 1,
          b => 2,
          c => 'cucu',
          d => undef,
          r => 1,
          br => 2,
          cr => 'cucu',
          dr => '321312321',

        );

my $c = %a;

print $c;

结果是5/8,我不明白这代表什么。我在某处读到了这个 fraction 查找结果中的数字可能代表散列中的桶数,但显然不是这种情况。

有谁知道如何在标量上下文中评估perl哈希值?

修改

我添加了一些其他的哈希值来打印:

use strict;
use warnings;

use 5.010;


my %a = ( a => 1,
          b => 2,
          c => 'cucu',
          d => undef,
          r => 1,
          br => 2,
          cr => 'cucu',
          dr => '321312321',

        );

my $c = %a;

say $c; # 5/8


%a = ( a => 1,
       b => 21,
       c => 'cucu',
       br => 2,
       cr => 'cucu',
       dr => '321312321',

      );

 $c = %a;

say $c; # 4/8

%a = ( a => 1,
       b => 2,
       c => 'cucu',
       d => undef,
       r => 1,
       br => 2,
       cr => 'cucu',
       dr => '321312321',
       drr => '32131232122',
      );

 $c = %a;

say $c; #6/8

那么,你在哈希中调用像a => 1桶这样的'元组'?在这种情况下,为什么最后一个哈希在有9'元组'时仍然有8分母?

直到现在,谢谢大家的答复:)

5 个答案:

答案 0 :(得分:23)

哈希是链表的数组。散列函数将密钥转换为一个数字,该数字用作存储值的数组元素(“bucket”)的索引。链表处理多个键散列到同一索引(“碰撞”)的情况。

分数的分母是桶的总数。

分数的分子是具有一个或多个元素的桶的数量。

对于具有相同元素数量的哈希值,数字越大越好。返回6/8的碰撞比返回4/8的碰撞少。

答案 1 :(得分:8)

来自perldoc perldata

  

如果在标量上下文中计算哈希值,则在哈希值时返回false   是空的。如果有任何键/值对,则返回true;更多   确切地说,返回的值是一个由数字组成的字符串   用桶和分配的桶数,用a分隔   斜线。

在您的情况下,您有五个值(12''cucu'undef'321312321')已被映射到八个密钥(abcdrbrcrdr )。

答案 2 :(得分:2)

使用过的桶的数量大约是键的数量;分配的桶一直是2的最低功率。键的数量。 5个键将返回5/8。大量的唯一键变得越来越慢,因此只有列表(1..128)的散列%h,具有64个键/值对,以某种方式获得标量值50/128。

但是,一旦哈希分配了它的桶,即使你缩小哈希值,它们仍将保持分配状态。我只用9对做了哈希%h,因此9/16标量;然后,当我重新分配%h只有一对时,它的标量值是1/16。

这实际上是有意义的,因为它可以让你测试哈希的大小,就像一个简单数组的标量一样。

答案 3 :(得分:1)

过分关注这个小数模式(作为散列内部细节的指标),可能会令人困惑。标量值的一个方面是&#34;标量值&#34;对于可能每个Perl程序都很重要的哈希值,也就是说,如果在 布尔上下文 中将其视为 true ,请参阅示例:< / p>

if (%h) {
    print "Entries in hash:\n";
    for my $k (sort keys %h) {
        print "$k: $h{$k}\n";
    }
}

perldoc perldata, section Scalar-values中,您可以阅读

  

[...]布尔上下文只是一种特殊的标量上下文,不会转换为字符串或数字。

以及之后的某些段落

  

如果在标量上下文中计算哈希值,则在哈希值时返回false   是空的。如果有任何键/值对,则返回true [...]

答案 4 :(得分:1)

自Perl 5.25起,行为已更改。参见perldata for Perl 5.26

在Perl 5.25之前,返回的值是一个字符串,其中包含 已用存储桶数和已分配存储桶数,以 斜线。这仅在确定Perl是否 内部哈希算法在数据集上的效果不佳。对于 例如,您将10,000个东西粘贴在一个哈希中,但在其中评估%HASH 标量上下文显示1/16,这意味着十六分之一中的一个 桶已被触及,大概包含您所有的10,000 项目。这不应该发生。

从Perl 5.25开始,返回值已更改为 哈希。如果您需要访问旧的行为,可以使用 改为Hash::Util::bucket_ratio()