Ruby散列排列

时间:2011-10-04 17:21:05

标签: ruby arrays hash permutation ruby-1.9

有没有快速的方法来获得给定哈希的(随机)排列?例如,对于数组,我可以使用{/ 3}}方法,如

ruby-1.9.2-p180 :031 > a = (1..5).to_a
 => [1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :032 > a.sample(a.length)
 => [3, 5, 1, 2, 4] 

对于哈希,我可以在哈希键上使用相同的方法,并使用

构建新哈希
ruby-1.9.2-p180 :036 > h = { 1 => 'a', 2 => 'b', 3 => 'c' }
 => {1=>"a", 2=>"b", 3=>"c"} 
ruby-1.9.2-p180 :037 > h.keys.sample(h.length).inject({}) { |h2, k| h2[k] = h[k]; h2 }
 => {3=>"c", 2=>"b", 1=>"a"} 

但这太丑了。哈希是否有任何“样本”方法可以避免所有代码?

更新正如@Michael Kohl在评论中所指出的,这个问题仅对ruby 1.9.x有意义。因为在1.8.x中Hash是无序的,所以没有办法做到这一点。

3 个答案:

答案 0 :(得分:9)

略微改进的mu太短了答案:

h = Hash[h.to_a.shuffle]

答案 1 :(得分:4)

只需在您的阵列版本中添加to_aHash[]即可获得哈希版本:

h = Hash[h.to_a.sample(h.length)]

例如:

>> h = { 1 => 'a', 2 => 'b', 3 => 'c' }
=> {1=>"a", 2=>"b", 3=>"c"}
>> h = Hash[h.to_a.sample(h.length)]
=> {2=>"b", 1=>"a", 3=>"c"}

答案 2 :(得分:0)

你真的需要改组,还是只需要一种方法来访问/迭代一个随机密钥?

否则,一个可能更便宜的解决方案是将散列键洗牌并根据这些散列键的排列访问您的项目

h = your_hash
shuffled_hash_keys = hash.keys.shuffle

shuffled_hash_keys.each do |key|
  # do something with h[key]
end

我相信(但需要一个带有基准的证明)这可以避免构建全新哈希的需要/成本,如果你有大哈希可能更有效(你只需支付数组排列的成本) )