Удалить значение из Perl хеша массивов хешей

Я пытаюсь удалить значения из хэша массивов хэшей, которые я создал с помощью следующего кода:

while ((my $Genotype1, my $Fitness1) = each (%Normalisedfithash)) {
  while ((my $Parent1A, my $TallyP1) = each(%P1Tallyhash)) {
    my $ParentTally = 0;
    my $SecondParent = {
      Parent2 => $Parent1A,
      Tally => $ParentTally,
    };
    push @{ $StoredParentshash{$Genotype1}}, $SecondParent;

Я пытался удалить значения из %StoredParentshash, где Tally равно нулю. (У меня есть дополнительный код, который обновляет Tally, но некоторые из них не обновляются, и я хочу, чтобы они были удалены из хэша).

Я написал следующее:

for my $Parent (keys %StoredParentshash) {
  my $aref1 = $StoredParentshash{$Parent};
  for my $hashref1 (@$aref1) {
    my $Tally =  $hashref1->{'Tally'};
    if ($Tally == 0){
      delete $hashref1->{'Tally'};
      delete $hashref1->{'Parent2'};
    }
  }
}

Этот код удаляет данные, но когда я использую Data::Dumper, структура, которую я возвращаю, выглядит так:

 '7412' => [
        {},
        {
          'Tally' => 1,
          'Parent2' => '2136'
        },
        {},
        {},
        {},

Как я могу полностью удалить ключи, где Tally равно нулю, вместо того, чтобы оставить {}?

Спасибо!


person Lisa    schedule 30.04.2012    source источник
comment
Было бы проще, если бы вы также предоставили входные данные. Еще лучше была бы наглядная демонстрация проблемы.   -  person ikegami    schedule 30.04.2012
comment
Приносим извинения, исходные данные исходно поступают из базы данных Mysql, которая затем изменяется по-разному, чтобы сделать% Normalisedfithash и% P1Tallyhash - я подумал, что было бы сложно объяснить, откуда они взялись, но теперь я вижу, что я должен был предоставить больше информации   -  person Lisa    schedule 30.04.2012
comment
Вы правы в том, что нам не нужно знать, откуда оно взялось. Я просто имел в виду иллюстрацию ввода, подобную той, которую вы предоставили для текущего вывода.   -  person ikegami    schedule 30.04.2012


Ответы (2)


Код, который, как вы говорите, сгенерировал структуру данных, неверен, так как в нем отсутствуют две закрывающие фигурные скобки.

Вы должны показать свой реальный код со сбалансированным { .. } или дампом %StoredParentshash, прежде чем мы сможем вам должным образом помочь.

Если Tally и Parent2 - единственные ключи в хешах SecondParent, тогда вы должны написать что-то вроде

for my $children (values %StoredParentshash) {
  @$children = grep $_->{Tally} != 0, @$children;
}
person Borodin    schedule 30.04.2012
comment
Это были единственные ключи - спасибо. (по ошибке я не скопировал две последние фигурные скобки) - person Lisa; 30.04.2012

Ваши данные выглядят так:

my %StoredParentshash = (
   key1 => [
      {
         Tally => ...,
         ...
      },
      ...
   ],
   ...
);

И вы хотите удалить некоторые элементы массива. Обычно для этого я использую grep.

@array = grep keep_condition(), @array;

Здесь не исключение.

for my $array (values(%StoredParentshash)) {
   @$array = grep $_->{Tally}, @$array;
}

И чтобы удалить все пустые массивы:

for my $key (keys(%StoredParentshash)) {
   delete $StoredParentshash{$key} if !@{ $StoredParentshash{$key} };
}

Или в сочетании:

for my $key (keys(%StoredParentshash)) {
   my $array = $StoredParentshash{$key};
   @$array = grep $_->{Tally}, @$array;
   delete $StoredParentshash{$key} if !@$array;
}
person ikegami    schedule 30.04.2012
comment
В результате @$array будет содержать только хэши со значением false элемента Tally. Это в значительной степени противоположно коду OP, который пытался удалить все элементы с нулевым элементом Tally. - person Borodin; 30.04.2012
comment
@Borodin, Исправлено. (Как я сказал оператору, было бы лучше, если бы он представил работоспособную демонстрацию проблемы. Тогда было бы тривиально проверить мое решение.) - person ikegami; 30.04.2012
comment
Теперь некоторые массивы остаются совершенно пустыми, например, '7412' = ›[] - как я могу их удалить? - person Lisa; 01.05.2012
comment
@Lisa, Сделайте еще одно сканирование, удалите ключи внешнего хеша, которые имеют значение для ссылки на пустой массив. Код добавлен в ответ. - person ikegami; 01.05.2012