def unique_randoms(n, max = nil)
seen = {}
n.times{x = rand max; seen[x] ? redo : seen[x] = 1}
seen.keys
end
It's a little more terse than it needs to be. Here is a more explicit version:
def unique_randoms(n, max = nil)
seen = {}
n.times do
x = rand max
redo if seen[x]
seen[x] = true
end
seen.keys
end
If you need a large number of randoms it is faster to use the Array sort method:
def unique_randoms(n, max)
(0..max).sort{rand}[0..n]
end
This leads us to a solution to quickly getting random rows through ActiveRecord:
def random(scope, num_randoms)
count = scope.count
unique_randoms(num_randoms, count){|i| scope.first :offset => i}
end
The above solution is appropriate for large result sets where :order => 'RAND()' is inefficient, and for small quantities of random rows. Each random row adds a query to this solution.