foreach循环比使用perl更大

时间:2013-04-30 08:16:10

标签: perl if-statement foreach conditional-statements

我有哈希哈希,我需要将所有“主密钥”相互比较(这些是数字)。这是我的代码:

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...
    }
}
  • 谢谢:)

3 个答案:

答案 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;

此过程所需的时间将随着两个哈希中的键总数线性增加,因此对于非常大的数据集仍然有效。