对于哈希,是否有等效的“Array :: sample”?

时间:2013-03-16 20:55:08

标签: ruby hash random

我希望从哈希中提取n个随机键值对。

5 个答案:

答案 0 :(得分:47)

Hash[original_hash.to_a.sample(n)]

对于Ruby 2.1,

original_hash.to_a.sample(n).to_h

答案 1 :(得分:32)

我不知道这种方法。你还可以做点什么:

h[h.keys.sample]

如果您需要对多个元素进行采样,则代码必须更加复杂。

编辑:要获取键值对而不是只能使用以下值的值:

keys_sample = h.keys.sample(n)
keys_sample.zip(keys_sample.map{|k| h[k])

答案 2 :(得分:2)

如果您的样本只有一个元素,您可以使用它:

sample = h.keys.sample
h.select { |k,v| k == sample }

或者如果您的样本包含多个元素,请使用:

n = 2
sample = h.keys.sample(n)
h.select { |k,v| sample.include?(k) }

答案 3 :(得分:2)

阅读排名靠前的答案,我会选择取决于

  1. 如果您想从哈希中仅对一个元素进行采样,@Ivaylo Strandjev's solution仅依赖于哈希查找和Array#sample

    hsh[hsh.keys.sample]
    
  2. 要对多个哈希元素进行采样,@sawa's answer利用Array#to_h

    hsh.to_a.sample(n).to_h
    
  3. 请注意,as @cadlac mentionshsh.to_a.sample.to_h无法正常工作。它会提高

    TypeError: wrong element type String at 0 (expected array)
    

    因为在这种情况下Array#sample只返回元素数组,而不是包含元素数组的数组。

    解决方法是他的解决方案,提供n = 1作为参数:

    hsh.to_a.sample(1).to_h
    

    PS:不寻找upvotes,只是将其作为Ruby更新人的解释。

答案 4 :(得分:0)

实现这一目标的一种方法:

rank_hash = {"Listen" => 1, "Download" => 60, "Share" => 150, "Purchase" => 700 }

rank_array = rank_hash.to_a

调用此方法获取k / v对的随机数组样本:

rank_array[rand(0..3)]

或者这不是硬编码数组的长度:

rank_array[rand(0..(rank_array.length) -1)]

示例:

["Download", 60]