Làm cách nào để sắp xếp ngẫu nhiên (xáo trộn) một mảng trong Ruby?


128

Tôi muốn có các mục mảng của tôi được xáo trộn. Một cái gì đó như thế này:

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

và cứ thế, ngẫu nhiên

Câu trả lời:


293

Được xây dựng ngay bây giờ:

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

3
Và nếu bạn muốn tự thực hiện nó: en.wikipedia.org/wiki/Fisher-Yates_shuffle
Joey

Hoặc nếu bạn muốn nó cho Ruby <1.9: yêu cầu 'backports'
Marc-André Lafortune

1
Hình như trong Ruby 1.8.7 cũng vậy.
Brian Armstrong

Điều đó hoàn toàn tuyệt vời.
sidney

1
Chỉ muốn thêm: nếu bạn muốn ảnh hưởng đến bộ sưu tập, hãy thêm một !sau cuộc gọi để xáo trộn. Không có !mảng xáo trộn được trả về, và chín muồi cho một nhiệm vụ.
Muyiwa Olu

27

Đối với ruby ​​1.8.6 (không có shuffle tích hợp):

array.sort_by { rand }

11
@Josh: Trang bạn liên kết để mô tả một thuật toán hoàn toàn khác. Lưu ý rằng sort_bychức năng của ruby không hoạt động như chức năng sắp xếp của javascript (hoặc chức năng sắp xếp của ruby ​​cho vấn đề đó), chỉ quan tâm xem số được tính có nhỏ hơn 0, 0 hay lớn hơn không. Thay vào đó sort_byhãy nhớ giá trị tính toán cho từng mục và sau đó sắp xếp các mục theo giá trị đó. Vì vậy, trong trường hợp này, mỗi mục được gán một số ngẫu nhiên và sau đó mảng được sắp xếp theo các số ngẫu nhiên đó.
sepp2k

Với một mảng kích thước lớn, việc sắp xếp này theo các số ngẫu nhiên cho mỗi mục có thể mất quá nhiều thời gian (O (NLogN), chúng ta có thể thực hiện trong một thời gian tuyến tính nếu chúng ta tạo một số ngẫu nhiên từ các mục trước đó mà chúng ta đã xáo trộn và sau đó trao đổi như vòng lặp tăng dần.
Downhillski

9

Đối với ruby ​​1.8.6 là ví dụ của sepp2k, nhưng bạn vẫn muốn sử dụng phương pháp "xáo trộn".

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]

chúc mừng


2

Mã từ Đá quý Backports chỉ cho Mảng cho Ruby 1.8.6. Ruby 1.8.7 trở lên được tích hợp sẵn.

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

Các của Ruby khía cạnh thư viện các phần mở rộng có một Randommô-đun cung cấp phương pháp hữu ích bao gồm shuffleshuffle!để một loạt các lớp lõi bao gồm Array, HashString.

Hãy cẩn thận nếu bạn đang sử dụng Rails vì tôi đã trải qua một số cuộc đụng độ khó chịu theo cách mà trò bịp bợm của nó đụng độ với ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.