在 Perl 中随机访问和修改顺序数据的最佳方法
Posted
技术标签:
【中文标题】在 Perl 中随机访问和修改顺序数据的最佳方法【英文标题】:Best way to randomly access and modify sequential data in Perl 【发布时间】:2021-08-07 23:30:49 【问题描述】:我的 Perl 程序的输入是一个文本文件,每行包含一个“项目”。例如,具有以下内容的文件:
item1 abc yyy any blabla 不管什么 item2 efg dod 不管 blabla mmm item3 hij naa 任何东西 gagaga 不管 gooo 1,2,3 item4 fff ahh 不管什么 blabla 什么 item5 noo kir 不管什么 bbbbbb hhhhhh item6 123 kkk 随便 blabla 随便 item7 555 yyy 任何东西 ghghgh a,b,c item8 777 yxy 随便 blabla 随便这个输入文件被读入一个数组(实际上是读入一个哈希数组,但对于这个例子,我们假设一个数组字符串):
my @items;
与每个项目相关联的是网络上的一个文件。对于输入文件中的每一项,程序都会在网络中搜索其关联文件:
my $associated_files_handle;
open ( $associated_files_filehandle, "> $associated_files_filename");
my $associated_file;
my @items_whose_associated_file_was_found;
my @items_whose_associated_file_was_not_found;
foreach my $item (@items)
# sub search_associated_file returns:
# - If associated file is found: path to the associated file, or
# - If associated file not found: undef
$associated_file = search_associated_file( $item );
if (defined $associated_file)
print $associated_files_filehandle, "$associated_file\n";
push @items_whose_associated_file_was_found, $item;
else
print $associated_files_filehandle, "\n";
push @items_whose_associated_file_was_not_found, $item;
假设找到了项目 1、2、3、6 和 8 的关联文件。上述循环完成后,输出文件将包含:
程序现在调用一个外部进程来生成项目 4、5 和 7 的关联文件:
my @missing_associated_files = generate_associated_files_of (\@items_whose_associated_file_was_not_found);
现在我有了所有项目的关联文件,并想更新输出文件以包含:
我的问题是最好的方法是什么?
一种方法是丢弃输出文件并重新运行我的程序(因为我在第一次运行结束时生成了丢失的关联文件,我知道所有关联文件都将在新运行中找到),但这是由于运行时间长,非常不受欢迎。
我正在寻找一种方法来跟踪丢失文件的索引,以便在它们生成后将它们插入到正确的位置。
我的软件技能仅限于我大约 40 年前在 Programming 101 中学到的知识,因此我非常感谢 Perl 代码形式的答案,尽管我的 S/W 素养有限,但我可以将其集成到我的程序中。
提前谢谢你。
【问题讨论】:
特德您在我编辑它以使其符合您的要求和最小可重复示例时关闭了问题。 这个问题还是很模糊的。您似乎正在生成某种列表,但不清楚如何生成。您询问“现有的已编译库文件的不完整列表”,但我们并不真正知道您的代码中有什么。那是数组@cells_missing_compiled_lib
吗?你的问题是如何比较两个数组?
“程序然后调用编译器在本地生成它们。” 您的示例代码没有显示在哪里以及如何完成。请澄清。
TLP,我更新了我的问题以包含一个说明性示例。也许现在更清楚了。
Håkon,你问这是在哪里完成的?就在我的问题中的“foreach”循环完成之后。这是怎么做到的?为什么它与我的问题有关?
【参考方案1】:
这是一个示例,说明如何在开始写入输出文件之前提前构建文件列表:
use feature qw(say);
use strict;
use warnings;
use experimental qw(signatures);
my @items = map "item_" . $_ 1..10;
my @files; # all files
my @items_not_found; # items whose associated file was not found
my @idx_not_found; # indexes of items not found
for my $i (0..$#items)
my $item = $items[$i];
my $associated_file = search_associated_file( $item );
if (defined $associated_file)
$files[$i] = $associated_file;
else
push @items_not_found, $item;
push @idx_not_found, $i;
# The program now invokes an external process to generate the associated files
# for the missing items:
@files[@idx_not_found] = generate_associated_files_of ( \@items_not_found);
my $fn = 'associated_files.txt';
open ( my $fh, '>', $fn ) or die "Could not open file '$fn': $!";
for my $file (@files)
say $fh "$file";
close $fh;
sub generate_associated_files_of($items)
my @files;
for my $item (@$items)
my ( $idx ) = $item =~ /item_(\d+)/;
die "Unexpected index" if !defined $idx;
push @files, "file_$idx";
return @files;
sub search_associated_file($item)
my ( $idx ) = $item =~ /item_(\d+)/;
my %not_ok_idx = map $_ => 1 4,5,7;
return undef if $not_ok_idx$idx;
return "file_" . $idx;
【讨论】:
感谢 Håkon 的回答。它主要回答了我关于如何跟踪缺少关联文件的项目的索引并在生成它们后将它们插入到数组文件中间的问题。但是,我怀疑 "map "item_" . $_ 1..10;"依赖于每个项目以字符串 'item_以上是关于在 Perl 中随机访问和修改顺序数据的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章