Come utilizzare i caratteri alternativi di chiavi in ​​perl hashes anche come chiavi?

StackOverflow https://stackoverflow.com/questions/9319460

  •  26-10-2019
  •  | 
  •  

Domanda

Il mio codice:

use strict;  
use warnings;

my $seq = "ATGGT[TGA]G[TA]GC";  
print "The sequences is $seq\n";  
my %regex = (  
   AG => "R",  
   TC => "Y",  
   GT => "K",  
   AC => "M",  
   GC => "S",  
   AT => "M",  
   CGT => "B",  
   TGA => "D",  
   ACT => "H",  
   ACG => "V",  
   ACGT => "N"  
);  

$seq =~ s/\[(\w+)\]/$regex{$1}/g;  
print "$seq\n";  

Il mio output ideale è: Atggtdgmgc ma nello scenario di cui sopra, poiché la mia chiave hash è AT e non TA, non funziona. Un modo per risolvere questo problema sarebbe aggiungere un altro valore chiave: ta => "m". Ma non posso farlo per tutte le coppie di valore chiave, poiché ci sono troppe possibilità.

Quindi c'è un modo migliore per affrontare questo problema ??

Grazie..

È stato utile?

Soluzione

Immagino che tu intenda che l'ordine delle cose tra parentesi non è importante, quindi AT è equivalente a TA, e TAG equivalente a TGA, eccetera.

Nota che l'altro Eric ha fatto un'ipotesi diversa. Non eri molto chiaro su ciò che volevi. "

Potresti ordinare le lettere.

sub key { join '', sort split //, $_[0] }

my @subs = (
   AG => "R",
   TC => "Y",
   GT => "K",
   AC => "M",
   GC => "S",
   AT => "M",
   CGT => "B",
   TGA => "D",
   ACT => "H",
   ACG => "V",
   ACGT => "N",
);  

my %subs;
while (@subs) {
    my $key = shift(@subs);
    my $val = shift(@subs);
    $subs{ key($key) } = $val;
}

# Die on unrecognized
$seq =~ s/\[(\w+)\]/ $subs{ key($1) } or die $1 /ge;

o

# Do nothing on unrecognized
$seq =~ s/\[(\w+)\]/ $subs{ key($1) } || $1 /ge;

Altri suggerimenti

Perl non ha modo di sapere che la chiave AT significa la stessa cosa di TA A meno che tu non lo dica in qualche modo. Se tutte le tue sequenze possono essere invertite, allora potresti fare qualcosa di simile:

for (keys %regex) {
   $regex{reverse $_} = $regex{$_}
}

Probabilmente dovresti anche controllare per assicurarti di non sovrascrivere alcuna chiavi esistenti.

In alternativa, è possibile modificare il regex:

$seq =~ s/\[(\w+)\]/$regex{$1} or $regex{reverse $1}
        or die "pattern $1 not found"/ge;  

Ancora una volta entrambi questi esempi ritengono che tutte le chiavi possano essere invertite. In caso contrario, dovrai inserire manualmente le inversioni o sviluppare una sorta di criteri di selezione per l'inversione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top