2013-09-29 43 views
1

我想要查找所有值均大於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

抱歉,如果不清楚。我想打印一個範圍congaing值超過0.3的開始和結束。 – EpiMan

+1

提示:split('',$ _)'(可以寫成'split'),在whitepsace上分割。 – ikegami

回答

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"; 
} 
+0

未檢查連續範圍 – ysth

+0

感謝@ysth,不知道我是如何錯過它的:P – NigoroJr

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"; 
} 

(每秒更新註釋顯示值)

+0

如何可以設置一個計數器來顯示我們在連續範圍內分組了多少個值,並顯示出有效值。例如「A 20 270 5 0.4,0.5,0.55,0.43,0.8」 – EpiMan

+0

更新爲顯示值 – ysth