2010-10-30 23 views
3

J'écris un sous en Perl pour fusionner 2 hachages de la même structure; de sorte que la fusion ($ a, $ b)comment fusionner 2 hachages profonds en perl

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

entraînerait

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

Ci-dessous est mon code pour la fusion, et il ne fonctionne pas. Comment puis-je le corriger? Je vous remercie.

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; 
} 
+0

duplication possible de [Comment puis-je combiner des hachages en Perl?] (Http://stackoverflow.com/questions/350018/how-can-i-combine-hashes-in-perl) – Ether

Répondre

8

À moins que vous faites cela juste pour apprendre comment faire, j'utiliser une solution premade comme Hash::Merge ou Hash::Merge::Simple.

+0

Oh, je n'ai pas sais qu'il existe. Merci – Martin08

2

Cela devrait être amplement suffisant:

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

Si vous ne voulez pas écraserait les doublons, peut-être parce que vous êtes préoccupé par les questions la commande, utiliser à la place:

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

L'avantage Cette opération très simple vous permet de développer des fonctionnalités avec des structures de données Perl de base, ce qui est essentiel sur le chemin de la maîtrise de la langue. Notez toutefois qu'il s'agit de copies en surface, donc les références seront partagées. Ce n'est pas une copie profonde.

J'ai utilisé each au lieu de keys afin qu'il évolue au cas où vous utiliseriez des hachages DBM avec des millions d'éléments.