Come ordinare casualmente (rimescolare) un array in Ruby?


128

Vorrei che i miei oggetti dell'array fossero confusi. Qualcosa come questo:

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

e così via, a caso

Risposte:


293

Costruito ora:

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

3
E se vuoi implementarlo da solo: en.wikipedia.org/wiki/Fisher-Yates_shuffle
Joey,

O se lo vuoi per Ruby <1.9: richiedi 'backports'
Marc-André Lafortune,

1
Sembra che sia anche in Ruby 1.8.7.
Brian Armstrong,

È assolutamente fantastico.
Sidney,

1
Volevo solo aggiungere: se si desidera influire sulla raccolta, aggiungere un !dopo la chiamata in ordine casuale. Senza l' !array mischiato viene restituito e maturo per un incarico.
Muyiwa Olu,

27

Per ruby ​​1.8.6 (che non ha shuffle incorporato):

array.sort_by { rand }

11
@Josh: la pagina che hai collegato descrive un algoritmo completamente diverso. Nota che la sort_byfunzione di ruby non funziona come la funzione di ordinamento di JavaScript (o la funzione di ordinamento di ruby ​​per quella materia), a cui importa solo se il numero calcolato è inferiore a zero, zero o maggiore di zero. sort_byRicorda invece il valore calcolato per ciascun elemento e quindi ordina gli articoli in base a quel valore. Quindi in questo caso a ciascun elemento viene assegnato un numero casuale e quindi l'array viene ordinato in base a tali numeri casuali.
sepp2k,

Con un array di grandi dimensioni questo ordinamento in base ai numeri casuali per ciascun elemento potrebbe richiedere troppo tempo (O (NLogN), potremmo farlo in un tempo lineare se generiamo un numero casuale dagli elementi precedenti che abbiamo mischiato e poi scambiamo come incremento dell'iteratore
Downhillski

9

Per ruby ​​1.8.6 come esempio di sepp2k, ma vuoi comunque usare il metodo "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]

Saluti


2

Codice dalla gemma Backports solo per l'array per Ruby 1.8.6. Ruby 1.8.7 o successivo è integrato.

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

La libreria di estensioni di Ruby Facets ha un Randommodulo che fornisce metodi utili tra cui shufflee shuffle!a un gruppo di classi principali tra cui Array, Hashe String.

Fai solo attenzione se stai usando Rails mentre ho sperimentato alcuni brutti scontri nel modo in cui il suo monkeypatch si è scontrato con Rails ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.