views:

125

answers:

4

I want to know if there is a much cleaner way of doing this. Basically, I want to pick a random element from an array of variable length. Normally, I would do it like this:

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

Is there something that is more readable / simpler to replace the second line? Or is that the best way to do it. I suppose you could do myArray.shuffle.first, but I only saw #shuffle a few minutes ago on SO, I haven't actually used it yet.

Thanks!

A: 

Try this

item = self[rand(self.length)]
Have you tried this? It doesn't want to work, neither does `myArray[self.length.rand]`
phoffer
How would this possibly work? You want to get the item from an array, not `self`.
Chuck
+3  A: 

Personally, I would prefer the method item = myArray.random_element. UPDATE: Before Ruby 1.8.7, you had to define the method yourself. See the answer for Marc-André Lafortune for a more modern view.

class Array
  def random_element
    self[rand(length)]
  end
end
grddev
or `... self[rand(length)] ...`
mykhal
If I only need it once or twice, I think I would just leave it as it is. However, for any semi-decent sized program, this is definitely the best way to do it. Thank you!
phoffer
@mykhal: thanks, fixed my answer.
grddev
+1  A: 

Wasn't there sample/choice method?

Anonymous scholar
Yup, http://apidock.com/ruby/Array/choice
Mladen Jablanović
+3  A: 

Just use Array#sample:

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

It is available in Ruby 1.9 (and upcoming 1.8.8), so if using an earlier version, require "backports". Note that in Ruby 1.8.7 it exists under the unfortunate name choice; it was renamed in later version so you shouldn't use it.

Marc-André Lafortune
I should have known that you would have a perfect answer for me (since most Ruby questions I browse here have your input somewhere). I am glad you pointed out the versioning; I am using 1.9.2. apidock (mladen's comment) does not have sample; neither does ruby-doc. In your opinion, what is the best reference for Ruby, updated to 1.9?
phoffer
On a side note, is it proper to change the "correct answer" after I have first selected another answer?
phoffer
Thanks :-) And yes, it is encouraged (see http://meta.stackoverflow.com/questions/19448/etiquette-for-selecting-answers )
Marc-André Lafortune