这是关于使用数字作为哈希键的。它没有直接回答问题,因为它没有比较数组提供的设施,但我认为这是放置信息的好地方。
假设使用这样的代码构建一个包含十个元素的哈希
use strict;
use warnings;
my %hash;
my $n = 1000;
for (1 .. 10) {
$hash{$n} = 1;
$n *= 1000;
}
然后我们查询它,寻找十次方的键。当然,整数乘以十最简单的方法就是加一个零,这样写就可以了
my $m = '1';
for (1 .. 100) {
print $m, "\n" if $hash{$m};
$m .= 0;
}
有输出
1000
1000000
1000000000
1000000000000
1000000000000000
1000000000000000000
我们输入了 10 个元素,但这只显示了 6 个。发生了什么?让我们看一下哈希中的内容。
use Data::Dump;
dd \%hash;
这个输出
{
"1000" => 1,
"1000000" => 1,
"1000000000" => 1,
"1000000000000" => 1,
"1000000000000000" => 1,
"1000000000000000000" => 1,
"1e+021" => 1,
"1e+024" => 1,
"1e+027" => 1,
"1e+030" => 1,
}
所以哈希没有使用我们想象的键。它以一种尝试模仿的方式将数字串起来是愚蠢的。
举一个更实际的例子,假设我们有一些圈子,想按区域收集到集合中。显而易见的事情是使用该区域作为哈希键,就像这个程序创建了 100,000 个随机整数直径最大为 1800 万的圆。
use strict;
use warnings;
use 5.010;
package Circle;
use Math::Trig 'pi';
sub new {
my $class = shift;
my $self = { radius => shift };
bless $self, $class;
}
sub area {
my $self = shift;
my $radius = $self->{radius};
pi * $radius * $radius;
}
package main;
my %circles;
for (1 .. 100_000) {
my $circle = Circle->new(int rand 18_000_000);
push @{ $circles{$circle->area} }, $circle;
}
现在让我们看看这些哈希键中有多少使用科学记数法
say scalar grep /e/, keys %circles;
它说(当然是随机的)
861
所以如果我们指定一个数字作为散列索引,那么真的没有一个整洁的方法可以知道 string perl 将使用什么。