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]

など、ランダムに

回答:


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

それとも、ルビー<1.9のためにそれをしたい場合:必要「バックポート」
マルク=アンドレ・Lafortune

1
Ruby 1.8.7にもあるようです。
ブライアンアームストロング

それは完全に素晴らしいです。
シドニー2015年

1
追加したいだけです:コレクションに影響を与えたい場合!は、シャッフルの呼び出しの後にa を追加します。!シャッフルされていない配列が返され、割り当ての準備ができています。
Muyiwa Olu 2016

27

Ruby 1.8.6の場合(シャッフルが組み込まれていない):

array.sort_by { rand }

11
@Josh:リンク先のページには、まったく異なるアルゴリズムが記述されています。rubyのsort_by関数は、計算された数値が0未満、0、または0より大きいかどうかにのみ注意を払う、JavaScriptのソート関数(またはその点ではルビーのソート関数)のように機能しないことに注意してください。代わりにsort_by、各アイテムの計算値を記憶し、その値でアイテムを並べ替えます。したがって、この場合、各アイテムには乱数が割り当てられ、配列はそれらの乱数でソートされます。
sepp2k 2011

大きなサイズの配列では、各項目の乱数によるこの並べ替えに時間がかかりすぎる可能性があります(O(NLogN)。シャッフルした前の項目から乱数を生成し、次のように入れ替えると、線形時間で実行できます。イテレータの増分
ダウンヒル

9

sepp2kの例としてのルビー1.8.6の場合でも、「シャッフル」メソッドを使用したい。

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

Array for Ruby 1.8.6のバックポートGemからのコード。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!を含むコアクラスの束にArrayHashおよびString

Railsを使用している場合は注意してください。モンキーパッチがRailsと衝突する方法でいくつかの厄介な衝突が発生したためです...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.