【问题标题】:Is there an equivalent to `Array::sample` for hashes?是否有等效于 `Array::sample` 的哈希值?
【发布时间】:2013-03-16 20:55:08
【问题描述】:

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

【问题讨论】:

  • 如果您能展示一个输入哈希的样本并多解释一下您尝试使用它的目的,将会有所帮助。从散列中获取随机键/值对很少有用,除非可能用于测试来自已知集合的随机输入。根据我的经验,这是一个非常奇怪的要求,让我觉得有些不妥。
  • 我也有同样的需求。我有一个哈希值,它也可以存储为一个哈希数组。并且能够从数组中抓取 n 个随机条目是有意义的。

标签: ruby hash random


【解决方案1】:
Hash[original_hash.to_a.sample(n)]

对于 Ruby 2.1,

original_hash.to_a.sample(n).to_h

【讨论】:

  • 如果我要从更大的散列中获取数据,这是慢还是坏主意?那么是否有替代方法可以尝试?
  • @appleLover 我想不出更好的了。
  • 我很好奇所以我对它进行了基准测试...以防其他人好奇gist.github.com/bendyorke/924612cba7432cbf36dd
【解决方案2】:

我不知道这种方法。您仍然可以执行以下操作:

h[h.keys.sample]

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

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

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

【讨论】:

  • 这不会返回 OP 想要的键值对,只返回随机键的值。
  • @theTinMan 是真的。取点。事实是,sawa 的解决方案是 那个 问题的最佳解决方案
【解决方案3】:

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

  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
    

请注意,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:不寻求点赞,只是添加它作为对 Ruby 新手的解释。

【讨论】:

  • 根据您的格式,hsh[hsh.keys.sample].keys 也可能是解决方案,如果您正在寻找特定哈希键下的子键。例如 users['John Doe'] = user_hash 不确定是否有更“红宝石”的方式来做到这一点。
【解决方案4】:

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

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

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

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

【讨论】:

  • 如果 h 只有一个元素,则使用= h。其他任何东西都是大材小用。
  • 我说如果 sample 只有一个元素。我的示例假定哈希具有多个键值对。用一个元素对哈希进行采样是没有意义的......
【解决方案5】:

实现此目的的一种方法:

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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多