说我循环浏览一些包含标题行的数据文件。例如,
[[1],[2],[3],[4],[5],[6],[7],[8],[9],[10]]
我想将所有标题行推送到>Header 1
data1
data2
data3
>Header 2
data4
data5
data6
>Header 3
数组,然后推送@headers
数组中的所有数据。该关系应为1:1,即@data
的第一个元素是">标题1" @headers
的第一个元素是" data1data2data3"。我怎么能做到这一点?到目前为止,我有
@data
将每行数据放入my @data;
my @headers;
while(<$fh>){
chomp($_);
if($_ =~ /(>)/){
push @headers, $_;
}
else{
push @data, $_;
}
}
中自己的索引中。基本上,如果该行以&#34;&gt;&#34;开头将其推送到@data
数组,否则只要下一行不以&#34;&gt;&#34;开头,就将其推送到@headers
数组。不太确定如何编写最后一部分。
答案 0 :(得分:1)
当没有标题时,您不需要push
到@data
。那会增加一个新元素。你想要做的是追加到最后一个元素。 Perl允许您使用索引[-1]
来获取数组的最后一个元素。因此,您可以在向@data
添加新元素的同时轻松地向@headers
添加新元素,因为它们对应。
use strict;
use warnings;
my (@headers, @data);
while (<DATA>) {
chomp; # no need for $_ here
if ( m/^>/ ) { # no need for $_ here either
push @headers, $_;
push @data, q{}; # the empty string
} else {
$data[-1] .= $_;
}
}
__DATA__
>Header 1
data1
data2
data3
>Header 2
data4
data5
data6
>Header 3
这会产生这些数据结构(用Data::Printer输出)。
[
[0] ">Header 1",
[1] ">Header 2",
[2] ">Header 3"
]
[
[0] "data1data2data3",
[1] "data4data5data6",
[2] ""
]
请注意,在大多数情况下,您不需要明确使用$_
,因为如果没有其他内容,许多运营商会默认使用它们。在括号内的模式中,您也不需要捕获组()
。您没有使用$1
,因此浪费了资源。
答案 1 :(得分:0)
按照您的编码,我们可以:
my (@data, @headers, @sequences);
while( <$fh> ) {
chomp($_);
if( $_ =~ /(>)/ ) {
push @headers, $_;
push @data, join @sequences;
@sequences = ();
}
else {
push @sequences, $_;
}
}
push @data, join @sequences;
每次找到新标题时,都会累积数据并重新开始序列。在循环结束时,您需要执行 final accummulation。
另请注意@simbabque评论不需要对大多数内置插件使用$_
。我没有更改代码以避免混淆。