如何从数组中随机选择?


559

我想知道是否有更干净的方法可以做到这一点。基本上,我想从可变长度的数组中选择一个随机元素。通常,我会这样:

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

有什么更可读/更容易替换第二行的东西吗?还是那是最好的方式。我想您可以做到myArray.shuffle.first,但是#shuffle几分钟前我才看到SO,但我实际上还没有使用它。


13
下面是一个很好的答案,但有关洗牌的一般要点。我可以想象对整个数组进行混音比仅仅获取一个随机数要费劲得多,所以这不是一个好的方向。
Derek Organ

Answers:


1127

只需使用Array#sample

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

在Ruby 1.9.1+中可用。为了也可以将其与Ruby的早期版本一起使用,可以使用 require "backports/1.9.1/array/sample"

请注意,在Ruby 1.8.7中,它以不幸的名称存在choice;它在以后的版本中被重命名,因此您不应该使用它。

尽管在这种情况下没有用,但是如果sample您需要多个不同的样本,请接受一个数字参数。


1
我应该知道您会为我提供一个完美的答案(因为我在这里浏览的大多数Ruby问题都有您的输入)。我很高兴您指出了版本控制;我正在使用1.9.2。apidock(mladen的评论)没有样品;ruby-doc也没有。您认为更新到1.9的Ruby最佳参考是什么?
Paul Hoffer

附带说明一下,在我第一次选择另一个答案后更改“正确答案”是否合适?
Paul Hoffer


我注意到您的编辑删除了1.8.8的内容。它仍然可以在1.8头中使用,而您只是在编辑问题,因为不会发生1.8.8?
安德鲁·格林

3
@Andrew:是的,我编辑了答案,因为1.8.8不会发生。它应该仍然是1.8头,但该分支已经死了:-(
马克-安德烈·Lafortune

84

myArray.sample(x) 还可以帮助您从数组中获取x个随机元素。


6
值得注意的是my_array.sample(1)!= my_array.sample
Redithion

5
@Redithion还值得注意的是,my_array.sample(1)== [sample]和my_array.sample == sample之间的区别明确提供了您的意思
Ekkstein


12

数组中随机项的随机数

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

可能的结果示例:

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

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

@fwilson以任意顺序随机收集对象。也适合测试不同的组合或生成存根数据
Mike Rapadas 2014年

为什么不扩展Array类?[] .total_random会更酷。来吧它的红宝石。它的目标!
蒂姆·克雷施默

这将永远不会返回空数组。您需要放置1 +在其他位置。
sawa's

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

这将从数组中返回一个随机元素。

如果您将使用下面提到的行

arr[1+rand(arr.count)]

那么在某些情况下它将返回0或nil值。

下面提到的行

rand(number)

始终将值从0返回到number-1。

如果我们使用

1+rand(number)

那么它可能返回数字,而arr [number]不包含任何元素。


-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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.