Perl hash while 循环找不到键值。

问题描述 投票:1回答:2

我被一个perl问题搞糊涂了,谁有什么办法?

I use one hash structure to store the keys and values like:
$hash{1} - > a;
$hash{2} - > b;
$hash{3} - > c;
$hash{4} - > d;
....
more than 1000 lines. I give a name like %hash

然后,我打算用一个循环语句来搜索所有的键,看是否与文件中的值匹配。

  for example, below is the file content:
  first line 1
  second line 2
  nothing
  another line 3

我的逻辑是。

while(read line){

    while (($key, $value) = each (%hash))
    {
      if ($line =~/$key/i){
         print "found";
   }
}

so my expectation is :
first line 1     - > return found
second line 2     - > return found
nothing
another line 3    - > return found
....

However, during my testing, only first line and second line return found, for 'another line3', the 
program does not return 'found'
Note: the hash has more than 1000 records.

所以我试着调试它,并在里面添加一些计数,并发现对于那些找到的情况,循环已经运行了600或700次,但对于 "另一行3 "的情况,它只运行了300次左右,并刚刚退出循环,没有返回发现。

知道为什么会发生这样的情况吗?

我还做了一个测试,如果我的哈希结构很小,比如只有10个键,逻辑就会工作。

我尝试使用foreach,看起来foreach没有这种问题。

perl foreach hash while-loop
2个回答
3
投票

你给出的伪代码应该可以正常工作,但可能有一个微妙的问题。

如果在你找到你的键并将其打印出来之后,你结束了while循环,那么下一次调用each时,它将继续你离开的地方。换句话说 "every "是一个迭代器,它将自己的状态存储在它迭代过的哈希中。

http:/blogs.perl.orgusersrurban201404do-not-use-each.html。 作者对此作了更详细的解释。他的结论是。

所以每一个都应该像在php中一样对待。像避免瘟疫一样避免它. 只有在你知道自己在做什么的优化情况下才使用它。


0
投票

OP并没有很好的阐述这个问题,提供的示例数据也很差,无法达到演示的目的。

以下示例代码是根据OP提供的问题描述进行的尝试。

重现 滤色镜数据 块、组成 $re_filter 包括 滤色镜 键,通过命令行中作为参数给出的文件来过滤出与之匹配的行。$re_filter.

use strict;
use warnings;

my $data = do { local $/; <DATA> };
my %hash = split ' ', $data;

my $re_filter = join('|',keys %hash);

/$re_filter/ && print for <>;

__DATA__
1   a
2   b
3   c
4   d

输入数据文件内容

first line 1
second line 2
nothing
another line 3

产量

first line 1
second line 2
another line 3
© www.soinside.com 2019 - 2024. All rights reserved.