Проблемы с удалением в hash perl

Другой хеш содержит имя как ключ (разделенный на _) и состоит из 4 частей (я сравниваю первые три части). Значение представляет собой строку, длину которой мне нужно сравнить, и если имя такое же и уже существует в хэше (первые три части), мне нужно сохранить строку с самой длинной длиной, и если длины равны, я не заботиться о том, что он держит. Я знаю, что с итерацией возникают проблемы, поскольку пары ключ-значение удаляются.

 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"; 
            }
        }
    }

person tonkscancode    schedule 29.07.2014    source источник
comment
взгляните на each, он позволяет безопасно удалять записи во время итерации.   -  person Hunter McMillen    schedule 29.07.2014
comment
В качестве предупреждения, при использовании each, позаботьтесь о том, чтобы цикл выполнялся до конца, иначе вы обнаружите, что в следующий раз, когда вы войдете в цикл, вы получите только оставшуюся часть хэша, который вы не повторяли в последний раз.   -  person Leeft    schedule 29.07.2014


Ответы (1)


Ваш код довольно запутанный, но я думаю, что приведенный ниже пример кода делает то, что вам нужно. Он работает путем копирования содержимого %anotherhash (пожалуйста, не используйте такие ужасные бессмысленные имена для ваших переменных) в %temphash по одному элементу за раз, и только если новое значение из %anotherhash длиннее, чем %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;
  }
}
person Borodin    schedule 29.07.2014
comment
лол, я не забуду использовать ужасные имена! Давно работаю, надоело называть! но я думаю, это должно сработать! Спасибо :) Подождите, но это не даст мне четвертую часть имени, которая мне нужна в окончательном выводе! - person tonkscancode; 29.07.2014
comment
Так что возьмите пример и измените его. в конце концов, ваш ник - Tonks 'Can' Code. Я не думаю, что здесь кто-то захочет писать за вас все решение. Мы здесь только для E.D.G.E - Объясняйте, Демонстрируйте, Направляйте, Ободряйте. - person Len Jaffe; 29.07.2014
comment
Присвоение вашим переменным ужасных имен, вероятно, увеличивает усталость :) Если вы напишете читаемый код и добавите несколько комментариев о том, почему вы делаете то, что делаете, будет легче устранять неполадки, и вы будете рады, что добавили комментарии, если посмотрите на код снова полгода спустя. - person Leeft; 29.07.2014
comment
@tonkscancode: Если вы правильно объяснили, как вы хотите, чтобы %temphash ухаживал за процедурой, и привели несколько примеров данных, то мы могли бы помочь вам лучше. На самом деле мне пришлось работать в обратном направлении от кода, который вы показываете, и пытаться понять, что вы хотели сделать. Есть еще вещи, которых я не понимаю, например, откуда берутся $realkey и $realkey_catstring и для чего нужны $sequence_realkey и $sequence_tempkey (вы их создаете, но не используете). Кроме того, ваш собственный код не делает ничего особенного для сохранения ключа fcomplete, поэтому мне нечего делать. - person Borodin; 29.07.2014
comment
обязательно добавлю комментарии, как только разберусь! Спасибо за помощь, очень ценю! - person tonkscancode; 29.07.2014