Problemas con eliminar en hash perl
-
21-12-2019 - |
Pregunta
Otro hash contiene el nombre como clave (dividido por _) y tiene 4 partes (estoy comparando las primeras tres partes).El valor es una cadena cuya longitud necesito comparar y si el nombre es el mismo y ya existe en el hash (las primeras tres partes), necesito mantener la cadena con la longitud más larga y si las longitudes son iguales, no importa cuál se queda.Sé que con la iteración se crean problemas a medida que se eliminan los pares clave-valor.
my %temphash=();
%temphash=%anotherhash;
foreach my $tempkey(keys %temphash){
my @tempkey_splitted = split /\_/, $tempkey;
my $tempkey_newfamily = $tempkey_splitted[0];
my $tempkey_newgenera = $tempkey_splitted[1];
my $tempkey_newspecies = $tempkey_splitted[2];
my $tempkey_catstring ="$tempkey_newfamily"."_$tempkey_newgenera"."_$tempkey_newspecies";
my $sequence_realkey="";
my $sequence_tempkey="";
my $length_realkey="";
my $length_tempkey="";
if ($realkey_catstring eq $tempkey_catstring){
$sequence_realkey = $anotherhash{$realkey};
$length_realkey = length($sequence_realkey);
#print "$anotherhash{$realkey}";
#print "$length_realkey";
$sequence_tempkey = $temphash{$tempkey};
#print "$anotherhash{$tempkey}";
$length_tempkey = length($sequence_tempkey);
# print "$length_tempkey";
if($length_realkey>$length_tempkey){
delete($temphash{$tempkey});
#print ">$realkey\n$anotherhash{$realkey}\n\n";
}
elsif($length_tempkey>$length_realkey){
delete($temphash{$realkey});
#print ">$tempkey\n$anotherhash{$tempkey}\n\n";
}
elsif($length_tempkey eq $length_realkey){
delete($temphash{$realkey});
}
}
else{
print "do nothing";
}
}
}
Solución
Su código es bastante complicado, pero creo que el siguiente código de ejemplo hace lo que necesita.Funciona copiando el contenido de %anotherhash
(por favor no utilice nombres tan espantosos y sin sentido para sus variables) para %temphash
un elemento a la vez, y sólo si el nuevo valor de %anotherhash
es más largo que el %temphash
my %temphash;
while (my ($key, $val) = each %anotherhash) {
my @key = split /_/, $key;
my $tempkey = join '_', @key[0,1,2];
my $tempval = $temphash{$tempkey};
unless (defined $tempval and length $tempval >= length $val) {
$temphash{$tempkey} = $val;
}
}