2017-10-03 4 views
0

Je souhaite accéder à une paire valeur/clé aléatoire à partir d'un hachage très volumineux. J'ai vérifié this réponse, ce qui m'a amené à cette solution -Accéder à une paire aléatoire à partir d'un hachage «grand»

original_hash.to_a.sample(n).to_h 

Il fonctionne bien, mais il convertit hachage entier à array pour chaque appel,
est-il une autre façon cela peut être fait efficacement pour une très grand hash?

+0

Ecrivez le problème entièrement dans le texte principal. Ne laissez pas le lecteur suivre un lien pour le comprendre. N'omettez pas l'explication dans le texte principal juste parce que vous pensez que vous l'avez écrit dans le titre. – sawa

+0

@sawa c'est exactement l'extrait que j'ai utilisé du lien, la ligne de code qui convertit le hachage en tableau et en retour en hachage. Et c'est ce que je cherche une alternative pour. – Darpan

+0

Non, pas du tout. – sawa

Répondre

0

Vous pouvez gernerate un nombre aléatoire d'abord, puis aller avec quelque chose comme

n = rand(large_hash.count) 
new_h = [large_hash.find.with_index { |_h,i| i == n }].to_h 
#alternatively new_h = large_hash.find.with_index { |h,i| [h].to_h if i == n } 

Maintenant new_h sera une valeur clé aléatoire paire Hash de la large_hash sans convertir l'ensemble large_hash à un Array. Ou une version plus obtus:

large_hash.find.with_index.with_object({}) do |((k,v),i),obj| 
    obj[k] = v if i == n 
end 

Note: ceci choisira une seule paire

+0

La complexité temporelle est ici 'O (N)', qui est comparable (même?) Au code de la question. Mais au moins la complexité de la mémoire est bien meilleure, oui. –

+0

Je suis un peu surpris que 'sample' ne soit pas défini sur' Enumerable' pour commencer. La mise en œuvre ressemblerait à ceci. – Max

0

Une option serait d'enregistrer toutes les clés dans une variable de mise en cache, puis d'accéder de manière aléatoire à une clé et de renvoyer la valeur de la clé. par exemple.

def random_paire(amount: 1) 
    @keys ||= @large_hash.keys 
    @keys.sample(amount).map {|key| { key => @large_hash[key] } } 
end 

Mais je pense que c'est seulement pratique si vous l'utiliserez dans une classe. Ce n'est pas une bonne option pour l'utiliser pour une méthode globalement disponible.