как объединить 2 глубоких хэша в perl - PullRequest
3 голосов
/ 30 октября 2010

Я пишу сабвуфер в Perl, чтобы объединить 2 хэша той же структуры;так что слияние ($ a, $ b)

$a = {
 k1 => { sk1 => 'v1' },
 k2 => { sk3 => 'v3', sk4 => 'v4' }
};
$b = {
 k1 => { sk2 => 'v2'},
 k3 => { sk5 => 'v5'} 
};

приведет к

$c = {
 k1 => { sk1 => 'v1', sk2 => 'v2' },
 k2 => { sk3 => 'v3', sk4 => 'v4' }
 k3 => { sk5 => 'v5'} 
};

Ниже приведен мой код для слияния, и он не работает.Как я могу это исправить?Спасибо.

sub merge {
 my ($old,$new) = @_;
 foreach my $k (keys($old)) {
  if (exists $new->{$k}) {
   if (ref($old->{$k}) eq 'HASH') {
    merge($old->{$k},$new->{$k});
   } else {
    $new->{$k} = $old->{$k};
   } 
  } else { 
   $new->{$k} = $old->{$k};
  }
 }
 return $new;
}

Ответы [ 2 ]

9 голосов
/ 30 октября 2010

Если вы не делаете это просто для того, чтобы узнать, как это делается, я бы использовал готовое решение, например Hash :: Merge или Hash :: Merge :: Simple .

2 голосов
/ 31 октября 2010

Это должно быть достаточно хорошо:

for my $href ($a, $b) {
    while (my($k,$v) = each %$href) {
        $c->{$k} = $v;
    }
}

Если вы не хотите блокировать дубликаты, возможно, из-за проблем с заказом, вместо этого используйте:

for my $href ($a, $b) {
    while (my($k,$v) = each %$href) {
        push @{ $c->{$k} },  $v;
    }
}

Преимущество выполнения этой очень простой операции самостоятельно заключается в том, что она помогает разрабатывать средства с базовыми структурами данных Perl, что очень важно для свободного владения языком.

Обратите внимание, что это поверхностные копии, поэтому ссылки будут предоставлены. Это не глубокая копия.

Я использовал each вместо keys, чтобы он масштабировался в случае использования хэшей DBM с миллионами элементов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...