Вложенный цикл foreach в Perl только один раз - PullRequest
2 голосов
/ 21 июня 2010

Я написал Perl-скрипт, который открывает два файла, которые содержат списки. Я хочу найти в первом списке элементы, которых нет во втором списке. Скрипт использует два цикла foreach. Внешний цикл проходит через каждую строку первого списка, извлекая необходимую информацию об элементе. Внутренний цикл проходит по второму списку, извлекая информацию об элементе, затем сравнивая эту информацию с элементом в первом списке.

Итак, идея заключается в том, что для каждого элемента в первом списке скрипт будет перебирать все элементы во втором списке в поисках совпадений. Проблема в том, что внутренний цикл foreach зацикливается только один раз. У меня была такая же проблема в PHP при циклическом просмотре таблиц MySQL во вложенных циклах while. Решением было сбросить индекс данных mysql, используя mysql_data_seek для каждой итерации внешнего цикла. Как я могу сделать это в Perl с файловыми дескрипторами?

Ответы [ 2 ]

8 голосов
/ 21 июня 2010

Если ваш внутренний цикл является итератором файлового дескриптора, то вам нужно будет сбрасывать его (например, закрывая и открывая файл) каждый раз, когда вы его достигнете.

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) {
       ...
    }
}
3 голосов
/ 21 июня 2010

Следует отметить, что код, который вы описываете, звучит очень неэффективно, O (n . m) . Вы можете добиться эффективности O (n + m) , поместив соответствующее содержимое одного файла в хеш, а затем итерируя другой файл только один раз.

...