Perl 中的嵌套循环数组引用



>我有 2 个文件,这种格式的行相同

例如

文件 1

string1:string2:string3
string4:string6:string6
string7:string8:string9

文件2

string1:string2:string3
string4:string6:string6
string7:string8:string9

必须用这个文件做一些工作,但我在写的开始,所以首先我做了这个

foreach my $firstFileString(<FILE1>){
    my @firstArray = split(/:/,$firstFileString);
    foreach my $secondFileString(<FILE2>){
    my @secondArray = split(/:/,$secondFileString);
    print "$firstArray[0]n";
    }
}

在继续程序之前,我通过输出产生了这个问题,在这一行中print "$firstArray[0]n";我总是string1。我期待string1, string4,string7

怎么可能?

提前谢谢。

程序在第一次读取时为每行file2打印string1

当内部循环退出,并且外部循环继续读取file1的第二行时,文件句柄FILE2已经位于文件末尾,因此没有更多要读取的内容,并且永远不会再次进入内部循环。

解决此问题的最佳方法是在外部循环打开file2,以便在您要通读文件时始终位于文件的开头。最好使用词法文件句柄($file1而不是FILE1(并使用while读取文件,一次读取一行文件,而不是foreach,后者读取整个文件,然后循环内存中的行。

use strict;
use warnings;
use 5.010;
use autodie;
open my $file1, '<', 'file1.txt';
while (my $line1 = <$file1>) {
  chomp $line1;
  my @fields1 = split /:/, $line1;
  open my $file2, '<', 'file2.txt';
  while (my $line2 = <$file2>) {
    chomp $line2;
    my @fields2 = split /:/, $line2;
    print "$fields1[0]n";
  }
}

输出

string1
string1
string1
string4
string4
string4
string7
string7
string7

更新

正如您正确所说,另一种方法是将整个file2读入数组。这样,您就不必多次重新打开并通读文件。

由于您将数据存储在内存中,因此您也可以将其拆分为字段,以节省多次执行此操作。该程序显示了如何操作。 file2被读入数组@file2,数组的每个元素都是一个字段数组。

现在,内部循环所要做的就是为数组的每一行设置$fields2。它是一个数组引用,因此字段是$fields2->[0]$fields2->[1]等。

use strict;
use warnings;
use 5.010;
use autodie;

open my $fh2, '<', 'file2.txt';
my @file2;
while (<$fh2>) {
  chomp;
  push @file2, [ split /:/ ];
}
open my $fh1, '<', 'file1.txt';
while (my $line1 = <$fh1>) {
  chomp $line1;
  my @fields1 = split /:/, $line1;
  for my $fields2 (@file2) {
    print "$fields1[0]n";
  }
}

问题是,您第一次通过外部循环将 FILE2 读到最后。 第二次通过外部循环,它位于文件的末尾,所以这段代码:

foreach my $secondFileString(<FILE2>){

什么都不做。 如果希望 FILE2 再次读取,可以在循环中关闭并打开它,或查找

foreach my $firstFileString(<FILE1>){
    my @firstArray = split(/:/,$firstFileString);
    seek FILE2, 0, SEEK_SET;
    foreach my $secondFileString(<FILE2>){
    my @secondArray = split(/:/,$secondFileString);
    print "$firstArray[0]n";
    }
}

虽然这样做的输出将是

string1
string1
string1
string4
string4
string4
string7
string7
string7

由于您在内部循环内打印,因此每件事都一式三份。 也许您打算在FILE2迭代之前在外循环中打印?

最新更新