【问题标题】:Nested foreach loop in perl only looping onceperl中的嵌套foreach循环仅循环一次
【发布时间】:2023-04-11 11:01:01
【问题描述】:

我编写了一个 perl 脚本,可以打开两个包含列表的文件。我想在第一个列表中查找不在第二个列表中的项目。该脚本使用两个 foreach 循环。外部循环遍历第一个列表的每一行,提取必要的项目信息。内部循环遍历第二个列表,提取项目信息,然后将该信息与第一个列表中的项目进行比较。

因此,想法是,对于第一个列表中的每个项目,脚本将遍历第二个列表中的所有项目,寻找匹配项。问题是内部 foreach 循环只循环一次。在嵌套的 while 循环中遍历 MySQL 表时,我在 PHP 中遇到了同样的问题。解决方案是使用 mysql_data_seek 为外循环的每次迭代重置 mysql 数据的索引。如何在 perl 中使用文件句柄执行此操作?

【问题讨论】:

  • 你能发布一些代码来解释你现在在做什么吗?
  • 如果你展示你的代码,人们将能够指出哪里出了问题。没有它,人们只能推测,而您只是在浪费他们(和您)的时间。
  • 没有代码我无法回答,但很可能您正在从外部循环重新使用内部循环中的某些内容,例如文件句柄或循环计数器。
  • 比较你的两个循环,看看你是否在内循环而不是外循环中犯了一个小错误。除此之外,您需要显示代码,否则我们不知道您想要什么。
  • 您不需要编写自己的代码来检查列表子集 - 有 CPAN 模块,更不用说内置的 ~~ 运算符了。

标签: perl foreach nested


【解决方案1】:

如果您的内部循环是一个文件句柄迭代器,那么您每次到达它时都需要重置它(例如,通过关闭并重新打开文件)。

foreach my $outer (@outer) {
   open INNER, '<', $inner_file;   # <--- need to add this
   while (my $inner = <INNER>) {
      ...
   }
   close INNER;                    # <--- optional with global scope filehandle
}

或者,如果您可以节省内存,您可以将文件句柄输出复制到循环外的数组,然后遍历该数组。

open INNER, '<', $inner_file;
my @INNER = <INNER>;
close INNER;

foreach my $outer (@outer) {
    foreach my $inner (@INNER) {
       ...
    }
}

【讨论】:

  • 谢谢,这是一个很好的答案,正是我所需要的。
  • @smfoote,不要只说“谢谢”,投票并检查它旁边的复选标记。将来,请发布一些带有您的问题的代码。
  • 我没有足够的声望来投票,我确实检查了复选标记。我知道拥有代码通常很有用,但我认为这个问题不需要代码,并且有证据表明 mobrule 能够在不看代码的情况下轻松回答问题。通常,当我添加我的代码时,答案和 cmets 会分散我真正想要弄清楚的内容,并且人们开始向我讲授我的代码质量。我不太喜欢那个。
  • @smfoote,是的,让人们尝试教你一些东西一定很糟糕。
  • 嗯,这并不容易 ;-) 但我同意其他所有人的观点,即使提供了一点代码,也更容易猜测 OP 需要知道什么(而这不是总是与所问的内容相同)并增加您获得有用答案的机会。
【解决方案2】:

需要注意的是,你描述的代码听起来效率很低,O(n.m)。您可以通过将一个文件的相关内容放入哈希中,然后只迭代另一个文件一次,从而获得 O(n+m) 效率。

【讨论】:

  • 如果我将第一个文件的相关内容放在哈希中,然后遍历第二个文件,我认为我仍然必须在第二个文件的每次迭代中遍历哈希。代码肯定会更高效,但两个文件都不是很大,所以差异不超过几秒钟。无论如何我应该修好它,所以我不会养成坏习惯。
  • @smfoote:如果您可以设计哈希以便您可以通过键进行比较,那么这种比较就哈希大小而言变为 O(1) 而不是 O(n)。哈希的“诀窍”是您甚至不必求助于二进制搜索 (O(log n))。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
相关资源
最近更新 更多