Comment puis-je vérifier si une clé existe dans une profonde Perl de hachage?
Si je comprendre correctement, appelant if (exists $ref->{A}->{B}->{$key}) { ... }
de printemps dans l'existence $ref->{A}
et $ref->{A}->{B}
même si ils n'existaient pas avant la if
!
Cela semble hautement indésirables. Alors, comment dois-je vérifier si un "profond" clé de hachage existe?
- Je suis étonné de voir que ce n'est pas dans la perlfaq, considérant qu'il est plus FA que la plupart de la Qs déjà là. Donnez-moi quelques minutes et je vais corriger ça 🙂
- Oh, regardez, il est là dans perlfaq4: Comment puis-je vérifier si une clé existe dans un multi-niveaux de hachage?. C'est essentiellement un résumé de ce fil. Grâce StackOverflow 🙂
Vous devez vous connecter pour publier un commentaire.
C'est beaucoup mieux d'utiliser quelque chose comme la autovivification module pour désactiver cette fonctionnalité, ou d'utiliser Data::Plongeur. Cependant, c'est l'une des tâches simples que je m'attends à un programmeur de savoir comment le faire sur son propre. Même si vous n'utilisez pas cette technique ici, vous devriez le savoir pour d'autres problèmes. C'est essentiellement ce qui
Data::Diver
est en train de faire une fois que vous dépouiller de son interface.C'est facile une fois que vous obtenez le coup de pied d'une structure de données (si vous ne souhaitez pas utiliser un module qui le fait pour vous). Dans mon exemple, j'ai créer un
check_hash
sous-routine qui prend un hash de référence et une référence de tableau de clés à vérifier. Il vérifie un niveau à la fois. Si la clé n'est pas là, elle ne retourne rien. Si la clé est là, qu'il nettoie le hachage juste qu'une partie du chemin et essaie de nouveau avec la touche next (suivant). Le truc, c'est que$hash
est toujours de la partie suivante de l'arbre pour vérifier. J'ai mis leexists
dans uneval
dans le cas où le niveau suivant n'est pas un hachage de référence. L'astuce est de ne pas échouer si la valeur de hachage à la fin du chemin est une sorte de fausse valeur. Voici la partie importante de la tâche:Ne soyez pas effrayés par tout le code dans la partie suivante. L'important, c'est juste le
check_hash
sous-routine. Tout le reste est de test et de démonstration:Ici la sortie (moins le vidage des données):
Maintenant, vous pourriez avoir quelques autres vérifier au lieu de
exists
. Peut-être que vous voulez vérifier que la valeur du chemin choisi est vrai, ou une chaîne, ou un autre de hachage de référence, ou que ce soit. C'est juste une question de fournir le droit de vérifier une fois que vous avez vérifié que le chemin existe. Dans cet exemple, je passe une sous-routine de référence qui permettra de vérifier la valeur que j'ai laissé avec. Je peux vérifier tout ce que j'aime:Et sa sortie:
Vous pouvez utiliser le autovivification pragma pour désactiver la création automatique de références:
Il est également lexicale, ce n'aurez qu'à le désactiver à l'intérieur de l'étendue que vous spécifiez dans.
Can't locate autovivification.pm in @INC
?!autovivification
pragma de CPAN, comme vous le feriez pour n'importe quel autre module.Vérifier chaque niveau pour
exist
rence, avant de s'intéresser au plus haut niveau.Si vous trouvez ça ennuyeux, vous pouvez toujours regarder sur CPAN. Par exemple, il est
Hash::NoVivify
.$ref->{A}{B}{C}
et$ref->{A}->{B}->{C}
?{}
et[]
sont inutiles et il semble préférable de les laisser sortir.&&
;and
pour le contrôle de flux uniquement&&
surand
dans la logique de comparaison.and
sur&&
dans le contrôle de flux.Prendre un coup d'oeil à Data::Plongeur. E. g.:
Assez laid, mais si $ref est compliqué, l'expression que vous ne souhaitez pas utiliser dans répété existe des tests:
n - 1
(oùn
est le nombre de niveaux dans la table de hachage) anonyme hashrefs pour le seul but d'éviter autovivication dans la cible de hachage (vous autovivify dans l'anonymat hashref à la place). Je me demande quelle est la performance par rapport aux multiples appels àexist
de la sane code.