2017-10-03 5 views
0

非常に大きなハッシュからランダムなキー値のペアにアクセスしたい。 私は、このソリューションに私を導いたthis答え、確認 - それはうまく動作しますが、それは各呼び出しのためarrayに全体のハッシュを変換し、
「大きい」ハッシュからランダムペアにアクセスする

original_hash.to_a.sample(n).to_h 

することは、これは非常にために効率的に行うことができ、他の方法はあります大きいhash

+0

を選択します。読者にそれを理解させるためのリンクを辿らせてはいけません。あなたがあなたがそれをタイトルに書いたと思ったからといって、本文の説明を省略しないでください。 – sawa

+0

@sawaこれは、私がリンクから使用した抜粋です。つまり、ハッシュを配列に変換してからハッシュに変換するコード行です。 これは私が代わりに探しているものです。 – Darpan

+0

いいえ、まったくありません。 – sawa

答えて

0

あなたは今new_hArrayに全体large_hashを変換せずにlarge_hashからランダムなキーと値のペアHashなります

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 } 

のようなもので行く最初の乱数をgernerateことができます。以上の鈍角バージョン:

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

注:これは、メインテキストで完全に問題を書く単一ペア

+0

ここで時間の複雑さは 'O(N)'です。これは質問のコードに匹敵します(同じ?)。しかし、少なくともメモリの複雑さは、より良い方法です。 –

+0

私は 'sample'が' Enumerable'で定義されていないことに少し驚いています。実装はこのようになります。 – Max

0

キャッシング変数にすべてのキーを保存してから、ランダムに1つのキーにアクセスしてキー値を返すというオプションがあります。例えば

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

しかし、これはクラスでこれを使用する場合にのみ実用的だと思います。グローバルに利用可能な方法に使用するのは、あまり良い選択肢ではありません。

関連する問題