在FOR循环中打印唯一值

时间:2014-10-15 12:06:04

标签: perl

我有两个文件myresult和annotation。两个文件中的数据看起来像是范围,但它们不是,这就是为什么我不能将它存储在一个数组中,我需要使用拆分运算符,以便我可以在for循环中使用它并进行比较。现在我需要打印来自$ i(myresult)和$ j(注释)的所有常见值而不重复(唯一)。我没有得到哪个条件以及如何实现它以获得所需的输出。我尝试使用%hash但无法实现。

myresult

0..351 
12..363  
24..375  
36..387  
48..399  
60..411  
.
.

注释

272..1042
1649..2629
3436..4752
4793..4975
5408..6022
6025..6252
.
.

CODE:

#!/usr/bin/perl
open( $inp0, "<myresult" )   or die "not found";
open( $inp2, "<annotation" ) or die "not found";
open( $out,  ">output" );
my @arr2 = <$inp0>;
my @arr4 = <$inp2>;
my $sum1 = 0;

foreach my $line1 (@arr2) {
    my ( $from1, $to1 ) = split( /\.\./, $line1 );

    foreach my $line2 (@arr4) {
        my ( $from2, $to2 ) = split( /\.\./, $line2 );

        for ( my $i = $from1; $i <= $to1; $i++ ) {
            for ( my $j = $from2; $j <= $to2; $j++ ) {
                if ( $i == $j ) {

                    print $out "$i \n";
                    $sum1++;
                }
            }
        }
    }
}

print "Unique values = $sum1";

2 个答案:

答案 0 :(得分:2)

您不需要遍历两个数组。如果范围的起点是升序,则可以使用以下代码:

#!/usr/bin/perl
use warnings;
use strict;

my @result = qw( 4..20 8..12 14..22 22..29 27..29 28..35 40..50 );

my @annot = qw( 1..5 11..13 25..37 45..55 );

my $from = (split /\.\./, $result[0])[0];
my $to   = (split /\.\./, $result[-1])[1];

for my $i ($from .. $to) {
    print "$i\n" if  grep inside($i, $_), @result
                 and grep inside($i, $_), @annot;
}

sub inside {
    my ($i, $range) = @_;
    my ($from, $to) = split /\.\./, $range;
    return ($from <= $i and $i <= $to)
}

答案 1 :(得分:2)

将每个数据集转换为值数组。

然后使用哈希计算两个列表中匹配的uniq值:

#!/usr/bin/perl -w
use strict;
use warnings;
use autodie;

use List::MoreUtils qw(uniq);

my @result = do {
    #open my $fh, '<', "myresult";
    open my $fh, '<', \ "0..351\n12..363\n24..375\n36..387\n48..399\n60..411\n";
    map { my ( $min, $max ) = /\d+/g; ( $min .. $max ) } <$fh>;
};

my @annot = do {
    #open my $fh, '<', "myresult";
    open my $fh, '<', \ "272..1042\n1649..2629\n3436..4752\n4793..4975\n5408..6022\n6025..6252\n";
    map { my ( $min, $max ) = /\d+/g; ( $min .. $max ) } <$fh>;
};

my %count;
$count{$_}++ for uniq(@result), uniq(@annot);

print join( ' ', sort { $a <=> $b } grep { $count{$_} == 2 } keys %count ), "\n";

输出:

272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411