views:

210

answers:

5

So i have an array of @horses = [] that i start filling with some random horses.

How can i check if my @horses array includes a horse that is already included (exists) in it?

I tried something like:

@suggested_horses = []
  @suggested_horses << Horse.find(:first,:offset=>rand(Horse.count))
  while @suggested_horses.length < 8
    horse = Horse.find(:first,:offset=>rand(Horse.count))
    unless @suggested_horses.exists?(horse.id)
       @suggested_horses<< horse
    end
  end

I also tried with include? but i saw it was for strings only. With exists I get the following error:

undefined method `exists?' for #<Array:0xc11c0b8>

So the question is how can I check if my array already has a horse included so that I dont fill it with the same horse?

Would be super grateful for any answers.

+1  A: 

This ...

horse = Horse.find(:first,:offset=>rand(Horse.count))
unless @suggested_horses.exists?(horse.id)
   @suggested_horses<< horse
end

Should probably be this ...

horse = Horse.find(:first,:offset=>rand(Horse.count))
unless @suggested_horses.include?(horse)
   @suggested_horses<< horse
end
Chris McCauley
+1  A: 

#include? should work, it works for general objects, not only strings. Your problem in example code is this test:

unless @suggested_horses.exists?(horse.id)
  @suggested_horses<< horse
end

(even assuming using #include?). You try to search for specific object, not for id. So it should be like this:

unless @suggested_horses.include?(horse)
  @suggested_horses << horse
end

ActiveRecord has redefined comparision operator for objects to take a look only for its state (new/created) and id

MBO
+2  A: 

Arrays in ruby don't have exists? method. And they've got include? method as described in docs. Something like

unless @suggested_horses.include?(horse)
   @suggested_horses << horse
end

should work out of box.

tomasz
+1  A: 

Array's include?method accepts any object, not just a string. This should work:

@suggested_horses = [] 
@suggested_horses << Horse.first(:offset => rand(Horse.count)) 
while @suggested_horses.length < 8 
  horse = Horse.first(:offset => rand(Horse.count)) 
  @suggested_horses << horse unless @suggested_horses.include?(horse)
end
John Topley
+1  A: 

Why not do it simply by picking 8 different numbers from 0 to Horse.count and use that to get your horses?

offsets = (0...Horse.count).to_a.sample(8)
@suggested_horses = offsets.map{|i| Horse.first(:offset => i) }

This has the added advantage that it won't cause an infinite loop if you happen to have less than 8 horses in your database....

Note: Array#sample is new to 1.9 (and coming in 1.8.8), so either upgrade your Ruby, require 'backports' or use something like shuffle.first(n).

Marc-André Lafortune