0

後でソートするための情報を含む 3 つの異なる HoA で重複するキーを見つけるコードをいくつか書きました。

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

my @intersect;
for my $key (sort keys %hash1) {
    if (exists $hash2{$key} && $hash3{$key} ) {
        my ($hit1, $percent_id1) = @{ $hash1{$key}[-1] };
        my ($hit2, $percent_id2) = @{ $hash2{$key}[-1] };
        my ($hit3, $percent_id3) = @{ $hash3{$key}[-1] };
        push @intersect, "$key\tC1:[$condition1]$hit1 [$percent_id1]\tC2:[$condition2]$hit2 [$percent_id2]\tC3:[$condition3]$hit3 [$percent_id3]\n\n";\n";
    }
}

次の場所に存在するキーも見つけるようにスクリプトを調整しようとしています。

  • hash1 と hash2、ただし hash3 は除く
  • hash2 と hash3、ただし hash1 は除く
  • hash1 と hash3、ただし hash2 は除く

私が使用しているのは(たとえば、最初のインスタンスの場合):

elsif (exists $hash2{$key} && !exists $hash3{$key} ) { # Is this the right way to specify a 'not exists'?
    my ($hit1, $percent_id1) = @{ $blast1{$key}[-1] };
    my ($hit2, $percent_id2) = @{ $blast2{$key}[-1] };
    push @intersect, "$key\tC1:[$condition1]$hit1 [$percent_id1]\tC2:[$condition2]$hit2 [$percent_id2]\n";
}

コードの後半で、@intersectランク付けするためにそれぞれをループします (以下で行われていることの詳細はほとんど関係ありません)。

foreach (@intersect) {
    chomp;
    my (@condition1_match) = ($_ =~ /C1:.*?Change:(-?\d+\.\d+|-?inf)/);
    @q_value1 = ($_ =~ /C1:.*?q:(\d+\.\d+)/);
    my (@percent_id) = ($_ =~ /C\d+:.*\[(\d+\.\d+)\]/);
    push @percentages, "@percent_id%";
    my (@condition2_match) = ($_ =~ /C2:.*?Change:(-?\d+\.\d+|-?inf)/);
    @q_value2 = ($_ =~ /C2:.*?q:(\d+\.\d+)/);
    my (@condition3_match) = ($_ =~ /C3:.*?Change:(-?\d+\.\d+|-?inf)/);
    @q_value3 = ($_ =~ /C3:.*?q:(\d+\.\d+)/);

    my $condition1_match = $condition1_match[0] // $condition1_match[1];
    my $condition2_match = $condition2_match[0] // $condition2_match[1];
    my $condition3_match = $condition3_match[0] // $condition3_match[1];

    if (abs $condition1_match > abs $condition2_match && abs $condition1_match > abs $condition3_match) {
            push @largest_change, $condition1_match;
        } 
        elsif (abs $condition2_match > abs $condition1_match && abs $condition2_match > abs $condition3_match) {
            push @largest_change, $condition2_match;
        }       
        else { push @largest_change, $condition3_match}

明らかに、キーが 3 つのハッシュではなく 2 つのハッシュに存在する場合、変数が undef である多くのインスタンスが存在するため、多くのUse of uninitialized value in...

if (defined ($variable ))各変数の前に??を付ける必要があります。

4

1 に答える 1

3
my %seen;
++$seen{$_} for keys(%hash1), keys(%hash2), keys(%hash3);
for (keys(%seen)) {
   next if $seen{$_} != 2;
   print("$_ is found in exactly two hashes\n");
}

このバージョンは、キーがどこから来たかを追跡します:

my %seen;
push @{ $seen{$_} }, 'hash1' for keys(%hash1);
push @{ $seen{$_} }, 'hash2' for keys(%hash2);
push @{ $seen{$_} }, 'hash3' for keys(%hash3);
for (keys(%seen)) {
   next if @{ $seen{$_} } != 2;
   print("$_ found in @{ $seen{$_} }\n");
}
于 2013-09-02T13:51:39.657 に答える