Определите элементы в хэше с критериями соответствия и несоответствия - PullRequest
0 голосов
/ 30 августа 2018

У меня есть два файла с разделителями табуляции: одна ссылка с тысячами записей а другой список миллионов критериев которые используются для поиска по ссылке.

Я делаю хэш справочного файла со следующим кодом

use strict;
use warnings;

#use Data::Dumper;
#use Timer::Runtime;

use feature qw( say );

my $in_qfn          = $ARGV[0];
my $out_qfn         = $ARGV[1];
my $transcripts_qfn = "file";

my %transcripts;

{
   open(my $transcripts_fh, "<", $transcripts_qfn)
      or die("Can't open \"$transcripts_qfn\": $!\n");

   while ( <$transcripts_fh> ) {
      chomp;
      my @refs = split(/\t/, $_);
      my ($ref_chr, $ref_strand) = @refs[0, 6];
      my $values =  {
         start => $refs[3],
         end   => $refs[4],
         info  => $refs[8]
      };

      #print Data::Dumper->Dump([$values]), $/; #confirm structure is fine
      push @{ $transcripts{$ref_chr}{$ref_strand} }, $values;
   }  
}

Затем я открываю другой входной файл, определяю элементы и анализирую хэш, чтобы найти критерии соответствия

while ( <$in_fh> ) {
  chomp;
  my ($x, $strand, $chr, $y, $z) = split(/\t/, $_);

  #match the reference hash for things equal to $chr and $strand
  my $transcripts_array = $transcripts{$chr}{$strand};

  for my $transcript ( @$transcripts_array ) {
     my $start = $transcript->{start};
     my $end   = $transcript->{end};
     my $info  = $transcript->{info};

     #print $info and other criteria from if statements to outfile, this code works
  }
}

Это работает, но я хотел бы знать, смогу ли я найти элементы в хэше, которые соответствуют $chr, но не $strand (который имеет двоичное значение любого знака).

Я поместил следующее в тот же блок while после предыдущего for, но оно не работает

my $transcripts_opposite_strand = $transcripts{$chr}{!$strand};

for my $transcript (@$transcripts_opposite_strand) {

   my $start = $transcript->{start};
   my $end   = $transcript->{end};
   my $info  = $transcript->{info};

   #print $info and other criteria from if statements
}

Я прошу прощения за фрагменты кода; Я пытался сохранить соответствующую информацию. Из-за размера файлов я не могу переборщить, перебирая построчно.

1 Ответ

0 голосов
/ 30 августа 2018

Оператор отрицания ! применяет логический контекст для своего аргумента. "+" и "-" оба имеют значение true в логическом контексте, поэтому ! $strand всегда имеет значение false, т.е. "" в контексте строки.

Либо хранить логическое значение в хэше

$strand = $strand eq '+';

или не используйте логическое отрицание:

my $transcripts_opposite_strand = $transripts{$chr}{ $strand eq '+' ? '-' : '+' };

Тернарный оператор может быть заменен более короткими, но менее читаемыми альтернативами, например

   qw( + - )[ $strand eq '+' ]

потому что в числовом контексте true интерпретируется как 1, а false как 0.

...