Làm thế nào để tôi chọn ngẫu nhiên từ một mảng?


559

Tôi muốn biết nếu có một cách sạch sẽ hơn nhiều để làm điều này. Về cơ bản, tôi muốn chọn một phần tử ngẫu nhiên từ một mảng có độ dài thay đổi. Thông thường, tôi sẽ làm như thế này:

myArray = ["stuff", "widget", "ruby", "goodies", "java", "emerald", "etc" ]
item = myArray[rand(myarray.length)]

Có cái gì dễ đọc / đơn giản hơn để thay thế dòng thứ hai không? Hoặc đó là cách tốt nhất để làm điều đó. Tôi cho rằng bạn có thể làm myArray.shuffle.first, nhưng tôi chỉ thấy #shufflevài phút trước trên SO, tôi chưa thực sự sử dụng nó.


13
Câu trả lời tốt dưới đây nhưng một điểm chung về shuffle. Tôi sẽ tưởng tượng việc có đầy đủ các mảng sẽ chuyên sâu hơn nhiều so với việc chỉ lấy một số ngẫu nhiên để nó không phải là một hướng tốt để đi.
Đàn organ Derek

Câu trả lời:


1127

Chỉ cần sử dụng Array#sample:

[:foo, :bar].sample # => :foo, or :bar :-)

Nó có sẵn trong Ruby 1.9.1+. Để có thể sử dụng nó với phiên bản cũ hơn của Ruby, bạn có thể require "backports/1.9.1/array/sample".

Lưu ý rằng trong Ruby 1.8.7, nó tồn tại dưới tên không may choice; nó đã được đổi tên trong phiên bản sau, vì vậy bạn không nên sử dụng nó.

Mặc dù không hữu ích trong trường hợp này, samplechấp nhận một đối số số trong trường hợp bạn muốn một số mẫu riêng biệt.


1
Tôi nên biết rằng bạn sẽ có một câu trả lời hoàn hảo cho tôi (vì hầu hết các câu hỏi về Ruby tôi duyệt ở đây đều có đầu vào của bạn ở đâu đó). Tôi vui mừng bạn chỉ ra phiên bản; Tôi đang sử dụng 1.9.2. apidock (bình luận của mladen) không có mẫu; ruby-doc cũng không. Theo bạn, đâu là tài liệu tham khảo tốt nhất cho Ruby, được cập nhật lên 1.9?
Paul Hoffer

Bên cạnh đó, việc thay đổi "câu trả lời đúng" có đúng không sau khi tôi chọn câu trả lời khác trước?
Paul Hoffer

1
Cảm ơn :-) Và vâng, nó được khuyến khích (xem meta.stackexchange.com/questions/19448/ mẹo )
Marc-André Lafortune

Tôi nhận thấy chỉnh sửa của bạn loại bỏ đề cập đến 1.8.8. Nó vẫn có sẵn trong 1.8 đầu và bạn chỉ đang chỉnh sửa câu hỏi vì 1.8.8 sẽ không xảy ra?
Andrew Grimm

3
@Andrew: Có, tôi đã chỉnh sửa câu trả lời của mình vì 1.8.8 sẽ không xảy ra. Nó vẫn phải ở 1,8 đầu, nhưng nhánh đó đã chết :-(
Marc-André Lafortune

84

myArray.sample(x) cũng có thể giúp bạn lấy x phần tử ngẫu nhiên từ mảng.


6
Điều đáng chú ý là my_array.sample (1)! =
My_array.sample

5
@Redithion Điều đáng chú ý, đó là sự khác biệt giữa: my_array.sample (1) == [sample] và my_array.sample == mẫu để cung cấp rõ ràng ý của bạn
Ekkstein


12

Số lượng ngẫu nhiên của các mục ngẫu nhiên từ một mảng

def random_items(array)
  array.sample(1 + rand(array.count))
end

Ví dụ về kết quả có thể:

my_array = ["one", "two", "three"]
my_array.sample(1 + rand(my_array.count))

=> ["two", "three"]
=> ["one", "three", "two"]
=> ["two"]

@fwilson bộ sưu tập ngẫu nhiên của các đối tượng theo thứ tự bất kỳ. Cũng tốt để thử nghiệm các kết hợp khác nhau hoặc tạo dữ liệu sơ khai
Mike Rapadas

Tại sao không mở rộng mảng Array? [] .total_random sẽ tuyệt hơn. Comeon ruby ​​của nó. Mục tiêu của nó!
Tim Kretschmer

Điều này sẽ không bao giờ trả lại một mảng trống. Bạn cần đặt 1 +ở một nơi khác.
sawa

0
arr = [1,9,5,2,4,9,5,8,7,9,0,8,2,7,5,8,0,2,9]
arr[rand(arr.count)]

Điều này sẽ trả về một yếu tố ngẫu nhiên từ mảng.

Nếu bạn sẽ sử dụng dòng được đề cập dưới đây

arr[1+rand(arr.count)]

sau đó trong một số trường hợp nó sẽ trả về giá trị 0 hoặc nil.

Dòng được đề cập dưới đây

rand(number)

luôn trả về giá trị từ 0 đến số 1.

Nếu chúng ta sử dụng

1+rand(number)

sau đó nó có thể trả về số và mảng [số] không chứa phần tử.


-2
class String

  def black
    return "\e[30m#{self}\e[0m"
  end

  def red
    return "\e[31m#{self}\e[0m"
  end

  def light_green
    return "\e[32m#{self}\e[0m"
  end

  def purple
    return "\e[35m#{self}\e[0m"
  end

  def blue_dark
    return "\e[34m#{self}\e[0m"
  end

  def blue_light
    return "\e[36m#{self}\e[0m"
  end

  def white
    return "\e[37m#{self}\e[0m"
  end


  def randColor
    array_color = [
      "\e[30m#{self}\e[0m",
      "\e[31m#{self}\e[0m",
      "\e[32m#{self}\e[0m",
      "\e[35m#{self}\e[0m",
      "\e[34m#{self}\e[0m",
      "\e[36m#{self}\e[0m",
      "\e[37m#{self}\e[0m" ]

      return array_color[rand(0..array_color.size)]
  end


end
puts "black".black
puts "red".red
puts "light_green".light_green
puts "purple".purple
puts "dark blue".blue_dark
puts "light blue".blue_light
puts "white".white
puts "random color".randColor
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.