是否有相当于哈希值的“Array::sample”?

问题描述 投票:0回答:6

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

ruby hash random
6个回答
52
投票
Hash[original_hash.to_a.sample(n)]

对于 Ruby 2.1,

original_hash.to_a.sample(n).to_h

43
投票

我不知道有这样的方法。你仍然可以这样做:

h[h.keys.sample]

如果您需要对多个元素进行采样,则代码必须稍微复杂一些。

编辑:要获取键值对而不仅仅是值,您可以执行以下操作:

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

7
投票

阅读排名最高的答案,我会选择这取决于

  1. 如果您想从哈希中采样仅一个元素,@Ivaylo Strandjev的解决方案仅依赖于哈希查找和

    Array#sample

    hsh[hsh.keys.sample]
    
  2. 要采样多个哈希元素,@sawa的答案利用了

    Array#to_h

    hsh.to_a.sample(n).to_h
    

请注意,正如@cadlac提到的那样

hsh.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:不寻求点赞,只是将其添加作为对 Ruby 新手的解释。


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) }

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]

0
投票
hash.slice(*hash.keys.sample(n))

slice 方法返回包含给定键的新哈希。只需选择一个按键样本即可。之前添加

*
将结果数组转换为切片方法的参数。

© www.soinside.com 2019 - 2024. All rights reserved.