Tenir compte de la HoH suivante:Accédez au hachage imbriqué dans Perl HoH sans utiliser de clés()?
$h = {
a => {
1 => x
},
b => {
2 => y
},
...
}
est-il un moyen de vérifier si une clé de hachage existe sur le second niveau imbriqué sans appeler keys(%$h)
? Par exemple, je veux dire quelque chose comme:
if (exists($h->{*}->{1})) { ...
(Je sais que vous ne pouvez pas utiliser *
comme caractère générique de clé de hachage, mais vous voyez l'idée ...)
Je suis en train de évitez d'utiliser keys()
car il remet le compteur du hachage et j'itérer sur $h
dans une boucle en utilisant:
while ((my ($key, $value) = each %$h)) {
...
}
la construction de la langue la plus approchante est le smart match operator (~~
) mentioned here (et aucune mention dans le perldoc perlref), mais même si ~~
était disponible dans la version de Perl Je suis contraint d'utiliser (5.8.4), d'après ce que je peux dire, cela ne fonctionnerait pas dans ce cas. Si cela ne peut pas être fait, je suppose que je vais copier les clés dans un tableau ou un hachage avant d'entrer dans ma boucle while
(c'est ainsi que j'ai commencé), mais j'espérais éviter les frais généraux.
Si vous copiez la liste des clés, vous n'avez plus besoin d'utiliser 'each% $ h' (malheureusement dangereux) et pouvez faire une boucle foreach à la place. Quelle est la taille de ce hachage? – Schwern
@Schwern: environ 24 000 clés (somme de tous les hashs imbriqués). Il contient toutes les attributions de privilèges pour une base de données Sybase. Je me rends compte que je peux juste éviter 'each', ou copier les clés, ou trouver une autre implémentation. Je pensais juste poser la question pour voir si c'était possible. – MisterEd
Je pense qu'il est possible de le faire efficacement, mais il faudrait changer l'interface ainsi que le code XS pour conserver l'itérateur de hachage après chaque itération au cas où il serait réinitialisé. La méthode 'each()' de perl5i a une telle interface, mais elle ne se défend pas contre votre cas. Il aimerait. https://github.com/schwern/perl5i/issues/210 – Schwern