我想找到所有值都大于0.3的连续范围。例如
A 1 10 0.2
A 20 40 0.4
A 60 75 0.5
A 90 100 0.55
A 200 205 0.43
A 211 270 0.8
A 450 511 0.1
A 513 550 0.0
B 1 10 0.6
B 50 200 0.7
B 300 350 0.8
B 400 500 0.9
B 600 711 0.4
B 800 900 0.2
输出:
A 20 270
B 1 711
我试过了:
while(<>){
chomp($_);
my @line = split("\t| ", $_);
my $letter=$line[0];
my @start;
my @end;
if($line[3]>0.3){
push (@start, $line[1]);
push (@end, $line[2]);
}
if($line[3]<0.3){
next;}
print $letter,"\t",$start[0],"\t",$end[-1],"\n";
}
但我明白了:
A 20 40
A 60 75
A 90 100
A 200 205
A 211 270
B 1 10
B 50 200
B 300 350
B 400 500
B 600 711
但我只希望每个适当范围的第一个开始和结束
答案 0 :(得分:3)
你没有说你是想要第一个或最后一个字母(或者如果你想把一个字母更改视为结束一个范围),所以我只是做第一个。
my $in_range;
my @ranges;
while (<>) {
chomp;
my ($letter, $start, $end, $value) = split /\t| /, $_;
if ($value <= .3) {
$in_range = undef;
}
elsif ($in_range) {
$in_range->{'end'} = $end;
push @{ $in_range->{'values'} }, $value;
}
else {
$in_range = {
'letter' => $letter,
'start' => $start,
'end' => $end,
'values' => [ $value ],
};
push @ranges, $in_range;
}
}
for my $range (@ranges) {
print join( "\t",
@$range{ qw/letter start end/ },
scalar( @{ $range->{'values'} } ),
join( ',', @{ $range->{'values'} } )
), "\n";
}
(根据评论更新以显示值)
答案 1 :(得分:1)
如何使用哈希?
#!/usr/bin/perl
use strict;
use warnings;
my %values;
while (<>) {
chomp;
my ($letter, $start, $end, $val) = split "\t| ";
next if (defined $values{$letter}{skip_rest});
if ($val > 0.3) {
$values{$letter}{min} = $start
if not defined $values{$letter}{min} or $values{$letter}{min} > $start;
$values{$letter}{max} = $end
if not defined $values{$letter}{max} or $values{$letter}{max} < $end;
}
elsif (defined $values{$letter}{min} and defined $values{$letter}{max}) {
$values{$letter}{skip_rest} = "true";
}
}
foreach my $letter (sort keys %values) {
print "$letter\t$values{$letter}{min}\t$values{$letter}{max}\n";
}