Ben
Ben

Reputation: 5172

Ruby // Random number between range, ensure uniqueness against others existing stored ones

Currently trying to generate a random number in a specific range; and ensure that it would be unique against others stored records.

Using Mysql. Could be like an id, incremented; but can't be it.

Currently testing other existing records in an 'expensive' manner; but I'm pretty sure that there would be a clean 1/2 lines of code to use

Currently using :

test = 0
Order.all.each do |ord|
  test = (0..899999).to_a.sample.to_s.rjust(6, '0')
  if Order.find_by_number(test).nil? then
    break
  end
end
return test

Thanks for any help

Upvotes: 1

Views: 204

Answers (3)

Rafa Paez
Rafa Paez

Reputation: 4860

Here your are my one-line solution. It is also the quicker one since calls .pluck to retrieve the numbers from the Order table. .select instantiates an "Order" object for every record (that is very costly and unnecessary) while .pluck does not. It also avoids to iterate again each object with a .map to get the "number" field. We can avoid the second .map as well if we convert, using CAST in this case, to a numeric value from the database.

(Array(0...899999) - Order.pluck("CAST('number' AS UNSIGNED)")).sample.to_s.rjust(6, '0')

Upvotes: 2

Arup Rakshit
Arup Rakshit

Reputation: 118271

I think, you can do something like below :

def uniq_num_add(arr)
 loop do
   rndm = rand(1..15)  # I took this range as an example
    # random number will be added to the array, when the number will 
    # not be present
    break arr<< "%02d" % rndm unless arr.include?(rndm)
  end  
end  

array = []

3.times do
 uniq_num_add(array)
end  

array # => ["02", "15", "04"]

Upvotes: 1

Uri Agassi
Uri Agassi

Reputation: 37409

I would do something like this:

# gets all existing IDs
existing_ids = Order.all.select(:number).map(&:number).map(&:to_i)

# removes them from the acceptable range
available_numbers = (0..899999).to_a - existing_ids

# choose one (which is not in the DB)
available_numbers.sample.to_s.rjust(6, '0')

Upvotes: 1

Related Questions