2009-12-03 12 views
1

J'ai besoin d'obtenir toutes les valeurs pour une certaine clé dans un hachage. Le hachage ressemble à ceci:Comment puis-je obtenir les clés de second niveau dans un hachage de hachage Perl?

$bean = { 
    Key1 => { 
       Key4 => 4, 
       Key5 => 9, 
       Key6 => 10, 
      }, 
    Key2 => { 
       Key7 => 5, 
       Key8 => 9, 
      }, 
}; 

J'ai juste besoin les valeurs Key4, Key5 et Key6 par exemple. Le reste n'est pas le point d'intérêt. Comment pourrais-je obtenir les valeurs?

Mise à jour: donc je n'ai un %bean j'ajouter les valeurs à la $bean comme ceci:

$bean->{'Key1'}->{'Key4'} = $value; 

espérons que cette aide.

+0

Voulez-vous dire que vous voulez rechercher récursivement le hachage pour les clés désirées? –

+0

Je veux obtenir les valeurs de key4, key5 et key6 récursivement. Je sais comment obtenir des valeurs à partir de clés, mais pas comment obtenir des valeurs à partir de clés dans des clés. – Przemek

+2

réponses * ne devrait pas * être en allemand, puisque les non-locuteurs allemands voudront également connaître la réponse –

Répondre

6
foreach my $key (keys %{$bean{Key1}}) 
{ 
    print $key . " ==> " . $bean{Key1}{$key} . "\n"; 
} 

devrait imprimer:

Key4 ==> 4 
Key5 ==> 9 
Key6 ==> 10 
+0

n'a pas fonctionné pour mon cas Bean est mon Hash son construire comme $ bean -> {'Key1'} et j'ai besoin de toutes les valeurs de cette clé. – Przemek

+0

@Przemek: si la seule différence est la capitalisation, vous devriez pouvoir l'ajuster assez facilement. (Votre question à l'origine dit «Bean», et l'affaire compte.) – Telemachus

+0

'$ bean {Key1} {$ key}' devrait être '$ bean -> {Key1} {$ key}', non? – Arkadiy

2

Si %bean est un hachage de hachages, $bean{Key1} est une référence de hachage. Pour fonctionner sur une référence de hachage comme vous le feriez sur un simple hachage, vous devez déréférencer, comme ceci:

%key1_hash = %{$bean{Key1}}; 

Et pour accéder à des éléments dans un hachage de hachages, vous utilisez la syntaxe comme ceci:

$element = $bean{Key1}{Key4}; 

Alors, voici une boucle qui imprime les clés et valeurs pour $bean{Key1}:

print $_, '=>', $bean{Key1}{$_}, "\n" for keys %{$bean{Key1}}; 

Ou si vous voulez juste les valeurs, et ne nécessitent pas les clés:

print $_, "\n" for values %{$bean{Key1}}; 

Consultez la documentation Perl suivante pour plus de détails sur l'utilisation des structures de données complexes: perlreftut, perldsc et perllol.

0

Un bon moyen de le faire - en supposant que ce que vous publiez est un exemple, plutôt qu'un seul cas particulier - serait recursively. Nous avons donc une fonction qui cherche un hachage à la recherche des clés que nous spécifions, s'appelle si elle trouve l'une des valeurs comme référence à un autre hachage.

sub recurse_hash { 
    # Arguments are a hash ref and a list of keys to find 
    my($hash,@findkeys) = @_; 

    # Loop over the keys in the hash 
    foreach (sort keys %{$hash}) { 

    # Get the value for the current key 
    my $value = $hash->{$_}; 

    # See if the value is a hash reference 
    if (ref($value) eq 'HASH') { 
     # If it is call this function for that hash 
     recurse_hash($value,@findkeys); 
    } 

    # Don't use an else in case a hash ref value matches our search pattern 
    for my $key (@findkeys) { 
     if ($key eq $_) { 
     print "$_ = $value\n"; 
     } 
    } 
    } 
} 

# Search for Key4, Key5 and Key6 in %Bean 
recurse_hash(\%Bean,"Key4","Key5","Key6"); 

donne cette sortie:

Key4 = 4 
Key5 = 9 
Key6 = 10 
+0

La récursivité est en fait une manière terrible de le faire. – friedo

+1

@friedo - Pourquoi est-ce une façon terrible? –

+0

@Dave, car vous accumulez inutilement des trames de pile pour traverser une structure de profondeur connue. Et même si la structure avait une profondeur arbitraire, une approche itérative serait beaucoup plus efficace. C'est la raison pour laquelle les langages fonctionnels comme Haskell ont une optimisation des appels. – friedo

1

Encore une autre solution:

for my $sh (values %Bean) { 
    print "$_ => $sh->{$_}\n" for grep exists $sh->{$_}, qw(Key4 Key5 Key6); 
}