如何在Ruby中随机排序(加扰)数组?


128

我想对我的数组项目进行打乱。像这样:

[1,2,3,4].scramble => [2,1,3,4]
[1,2,3,4].scramble => [3,1,2,4]
[1,2,3,4].scramble => [4,2,3,1]

等等,随机

Answers:


293

现在内置:

[1,2,3,4].shuffle => [2, 1, 3, 4]
[1,2,3,4].shuffle => [1, 3, 2, 4]

3
如果您想自己实施它,请访问:en.wikipedia.org/wiki/Fisher-Yates_shuffle
Joey

或者,如果您想要Ruby <1.9以下的版本,则需要'backports'
Marc-AndréLafortune,2009年

1
看起来它也在Ruby 1.8.7中。
Brian Armstrong 2010年

太棒了。
悉尼,2015年

1
只是想添加:如果您想影响集合!,请在调用shuffle之后添加一个。如果没有经过!改组的数组,则返回该数组,并且可以进行分配。
Muyiwa Olu

27

对于ruby 1.8.6(不内置随机播放):

array.sort_by { rand }

11
@Josh:您链接到的页面描述了完全不同的算法。请注意,ruby的sort_by功能与javascript的sort函数(或针对此问题的ruby的sort函数)不同,后者仅在乎计算所得的数字是小于零,零还是大于零。而是sort_by记住每个项目的计算值,然后按该值对项目进行排序。因此,在这种情况下,为每个项目分配一个随机数,然后按这些随机数对数组进行排序。
sepp2k 2011年

对于大型数组,按每个项目的随机数进行排序可能会花费太长的时间(O(NLogN),如果我们从之前洗过的项目中生成一个随机数,然后交换为迭代增量。
Downhillski

9

以ruby 1.8.6为例,例如sepp2k,但您仍想使用“ shuffle”方法。

class Array
  def shuffle
    sort_by { rand }
  end
end

[1,2,3,4].shuffle #=> [2,4,3,1]
[1,2,3,4].shuffle #=> [4,2,1,3]

干杯


2

来自Backports Gem的代码仅适用于Ruby 1.8.6的数组。内置Ruby 1.8.7或更高版本。

class Array
  # Standard in Ruby 1.8.7+. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
  def shuffle
    dup.shuffle!
  end unless method_defined? :shuffle

  # Standard in Ruby 1.8.7+. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
  def shuffle!
    size.times do |i|
      r = i + Kernel.rand(size - i)
      self[i], self[r] = self[r], self[i]
    end
    self
  end unless method_defined? :shuffle!
end

0

红宝石刻面扩展库具有Random模块,其提供有用的方法包括shuffleshuffle!一堆核心类,包括ArrayHashString

如果您使用的是Rails,请当心,因为我遇到了一些讨厌的冲突,其猴子修补程序与Rails的冲突...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.