Як довільно сортувати (кодирувати) масив у 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

Або якщо ви хочете, щоб це було для Ruby <1.9: вимагайте "backports"
Marc-André Lafortune

1
Схоже, це також у Ruby 1.8.7.
Брайан Армстронг

Це абсолютно дивовижно.
sidney

1
Просто хотів додати: якщо ви хочете вплинути на колекцію, додайте !після виклику перетасовування. Без !перетасованого масиву повертається і дозріває для призначення.
Muyiwa Olu

27

Для рубіну 1.8.6 (у якому немає вбудованого перемикання):

array.sort_by { rand }

11
@Josh: Сторінка, на яку ви посилаєтесь, описує зовсім інший алгоритм. Зауважте, що sort_byфункція ruby не працює як функція сортування javascript (або функція сортування ruby ​​для цього питання), яка переймається лише тим, чи є обчислене число менше нуля, нуля або більше нуля. Натомість sort_byзапам'ятовує обчислене значення для кожного елемента, а потім сортує елементи за цим значенням. Тож у цьому випадку кожному елементу присвоюється випадкове число, а потім масив сортується за тими випадковими числами.
sepp2k

Якщо масив великого розміру такого роду за випадковими числами для кожного елемента може зайняти занадто багато часу (O (NLogN), ми могли б зробити це в лінійний час, якщо генеруємо випадкове число з попередніх елементів, які ми перетасували, а потім поміняємо як приріст ітератора.
Downhillski

9

Для рубіну 1.8.6 як приклад sepp2k, але ви все ще хочете використовувати метод "перетасувати".

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модуль , який містить корисні методи , включаючи shuffleі shuffle!до зв'язки основних класів , включаючи Array, Hashі String.

Будьте обережні, якщо ви використовуєте Rails, коли я пережив неприємні сутички в тому, як його маніпулювання зіткнулося з "Рейлами" ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.