我有哈希哈希,我需要将所有“主密钥”相互比较(这些是数字)。这是我的代码:
foreach my $masterkey1 (keys %HOH){
foreach my $masterkey2 (keys %HOH){
if ($masterkey1 > $masterkey2){
... do some stuff...
}
}
}
但是,为了减少内存使用,可以将if语句与第二个foreach循环结合使用。
可能像
foreach my $masterkey1 (keys %HOH){
foreach my $masterkey2 (keys %HOH < $masterkey1){
... do some stuff...
}
}
答案 0 :(得分:2)
foreach my $masterkey1 (keys %HOH){
foreach my $masterkey2 (grep { $_ < $masterkey1 } keys %HOH){
... do some stuff...
}
}
我不确定这会更有效率。内部循环必须通过键进行两次传递:一次查找小于$masterkey1
的所有键,然后实际“执行某些操作”。
最好将密钥列表保存在单独的变量中:
@keys = keys %HOH;
foreach my $masterkey1 (@keys) {
foreach my $masterkey2 (@keys) {
if ($masterkey1 > $masterkey2) {
# do some stuff
}
}
}
答案 1 :(得分:1)
复制并排序键:
my @keys = sort { $a <=> $b } keys %HOH;
现在列表已经排序,您可以从列表末尾抓取每个键并将其与之前的所有内容进行比较:
while (my $masterkey1 = pop @keys) {
foreach my $masterkey2 (@keys) {
# do some stuff with $masterkey1 and $masterkey2
}
}
答案 2 :(得分:1)
您可能不希望有两个嵌套循环扫描您的密钥列表。运行所花费的时间将随着顶级哈希中的键数量呈指数级增长,这可能会导致重大问题,除非哈希值(并且将始终保持)相对较小。
你没有说出你真正想要实现的目标,但是,由于你要比较的值更大,你可能想要从sort
开始。我能给你的最好的功能与发布的代码相同:
my @masterkeys = sort { $a <=> $b } keys %HOH;
for my $outer (1 .. $#masterkeys) {
for my $inner (0 .. $outer - 1) {
# We already know $masterkeys[$outer] > $masterkeys[$inner],
# so no need to test that
... do some stuff ...
}
}
这至少会比你发布的代码更有效率,但是,如果你告诉我们你实际想要完成什么,我怀疑还有很多改进可能。
编辑:根据OP对此答案的评论,“我需要比较所有的主键并计算他们共有多少个键。”
以下是如何在两个哈希中找到公共密钥:
my %count;
$count{$_}++ for keys %hash1;
$count{$_}++ for keys %hash2;
my @keys_in_common = grep { $count{$_} == 2 } keys %count;
此过程所需的时间将随着两个哈希中的键总数线性增加,因此对于非常大的数据集仍然有效。