如何从数组中随机选择?

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

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

是否有更易于阅读/更简单的内容来取代第二行?还是说这是最好的方法。我想你可以做myArray.shuffle.first,但我只看到#shuffle几分钟前在SO,我实际上还没有使用它。

319680 次浏览

只需使用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接受一个数字参数,以便在需要多个不同样本的情况下使用。

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

数组中随机项的随机数

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"]
myArray.sample

将返回1个随机值。

myArray.shuffle.first

也将返回1个随机值。

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到1的值。

如果我们使用

1+rand(number)

然后返回number, arr[number]不包含任何元素。

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

下面是我在这里发布的一些答案上执行的一些基准测试,使用sample始终比其他的更快。

test_arr = ["stuff", "widget", "ruby", "goodies", "java", "emerald" ]


Benchmark.ips do |x|
x.report("1 - sample") { test_arr.sample }
x.report("2 - shuffle") { test_arr.shuffle.first }
x.report("3 - length") { rand(test_arr.length) }
x.report("4 - rand rand") { test_arr.sample(1 + rand(test_arr.count)) }
x.report("5 - rand el") { test_arr[rand(test_arr.count)]}
x.report("6 - switch") {
case rand(0..test_arr.length)
when 0
test_arr[0]
when 1
test_arr[1]
when 2
test_arr[2]
when 3
test_arr[3]
when 4
test_arr[4]
when 5
test_arr[5]
end
}


x.compare!

测试在MacBook Pro(15英寸,2018年)上运行,2.6 GHz 6核英特尔酷睿i7, 32 GB 2400 MHz DDR4

Warming up --------------------------------------
1 - sample   713.455k i/100ms
2 - shuffle   253.848k i/100ms
3 - length   489.078k i/100ms
4 - rand rand   236.396k i/100ms
5 - rand el   447.244k i/100ms
6 - switch   419.272k i/100ms
Calculating -------------------------------------
1 - sample      7.505M (± 3.2%) i/s -     37.813M in   5.044078s
2 - shuffle      2.661M (± 2.1%) i/s -     13.454M in   5.057659s
3 - length      5.021M (± 1.6%) i/s -     25.432M in   5.066159s
4 - rand rand      2.352M (± 2.4%) i/s -     11.820M in   5.029415s
5 - rand el      4.452M (± 2.2%) i/s -     22.362M in   5.025623s
6 - switch      4.324M (± 1.1%) i/s -     21.802M in   5.043294s


Comparison:
1 - sample:  7504636.7 i/s
3 - length:  5021326.6 i/s - 1.49x  (± 0.00) slower
5 - rand el:  4452078.6 i/s - 1.69x  (± 0.00) slower
6 - switch:  4323511.6 i/s - 1.74x  (± 0.00) slower
2 - shuffle:  2661267.7 i/s - 2.82x  (± 0.00) slower
4 - rand rand:  2351630.7 i/s - 3.19x  (± 0.00) slower