Wie kann man ein Array in Ruby zufällig sortieren (verschlüsseln)?

128

Ich möchte, dass meine Array-Elemente verschlüsselt werden. Etwas wie das:

[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]

und so weiter, zufällig

Daniel Cukier
quelle

Antworten:

293

Jetzt eingebaut:

[1,2,3,4].shuffle => [2, 1, 3, 4]
[1,2,3,4].shuffle => [1, 3, 2, 4]
Ron Gejman
quelle
3
Und wenn Sie es selbst implementieren möchten: en.wikipedia.org/wiki/Fisher-Yates_shuffle
Joey
Oder wenn Sie es für Ruby <1.9 wollen: benötigen Sie 'Backports'
Marc-André Lafortune
1
Sieht so aus, als wäre es auch in Ruby 1.8.7.
Brian Armstrong
Das ist absolut großartig.
Sidney
1
Ich wollte nur hinzufügen: Wenn Sie die Sammlung beeinflussen möchten, fügen Sie !nach dem Aufruf zum Mischen ein hinzu. Ohne das wird !das gemischte Array zurückgegeben und ist reif für eine Zuordnung.
Muyiwa Olu
27

Für Ruby 1.8.6 (in dem kein Shuffle eingebaut ist):

array.sort_by { rand }
sepp2k
quelle
11
@Josh: Die Seite, auf die Sie verlinkt haben, beschreibt einen völlig anderen Algorithmus. Beachten Sie, dass die Ruby- sort_byFunktion nicht wie die Sortierfunktion von Javascript (oder die Sortierfunktion von Ruby) funktioniert. Dabei ist es nur wichtig, ob die berechnete Zahl kleiner als Null, Null oder größer als Null ist. sort_byErinnert sich stattdessen an den berechneten Wert für jedes Element und sortiert die Elemente dann nach diesem Wert. In diesem Fall wird jedem Element eine Zufallszahl zugewiesen, und dann wird das Array nach diesen Zufallszahlen sortiert.
sepp2k
Bei einem großen Array kann diese Sortierung nach den Zufallszahlen für jedes Element zu lange dauern (O (NLogN)). Wir können dies in einer linearen Zeit tun, wenn wir aus den vorherigen Elementen, die wir gemischt haben, eine Zufallszahl generieren und diese dann austauschen Iterator-Inkrement.
Downhillski
9

Für Ruby 1.8.6 als Beispiel für sepp2k, aber Sie möchten immer noch die "Shuffle" -Methode verwenden.

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]

Prost

bry4n
quelle
2

Code aus dem Backports Gem für nur das Array für Ruby 1.8.6. Ruby 1.8.7 oder höher ist eingebaut.

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
Vizjerai
quelle
0

Die Ruby - Facets Bibliothek von Erweiterungen verfügt über ein RandomModul , die nützliche Methode einschließlich bietet shuffleund shuffle!einschließlich zu einer Reihe von Kern - Klassen Array, Hashund String.

Seien Sie nur vorsichtig, wenn Sie Rails verwenden, da ich einige böse Zusammenstöße in der Art und Weise erlebt habe, wie das Monkeypatching mit Rails '...

edavey
quelle