2

I want to generates a sequence of unique random number between 100 and 999. I want to make sure that no numbers are generated twice, to ensure that each number is unique. Here is what I came up with. It does not work. When i run it, the screen is just blank. Can anyone help me?

products = {}

def random_key(products)

  rand_key = rand(900) + 100

  while products.has_key?(rand_key)

    rand_key = rand(900) + 100

  end

end

puts random_key(products)
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
eddie tuell
  • 165
  • 4
  • 6

4 Answers4

16
a = (100..999).to_a.shuffle 

then every time you need a new id

new_id = a.pop

This guarantees that numbers are never reused. Of course, you'll have problems when you run out of elements on the array.

Marc Talbot
  • 2,059
  • 2
  • 21
  • 27
0

I believe the Marc Talbot answer is great! But put the answer in your context, let's explain a bit,

First, creates the ids.

ids = (100..999).to_a.shuffle 

Now, you can avoid the while, the method, the has_key?, and so on, and just call ids.pop

products[ids.pop] = {}

The final code version is:

ids = (100..999).to_a.shuffle 
products[ids.pop] = {}

The result will be:

irb(main):023:0> products[ids.pop] = {}
=> {}
irb(main):024:0> products[ids.pop] = {}
=> {}
irb(main):025:0> products[ids.pop] = {}
=> {}
irb(main):026:0> products[ids.pop] = {}
=> {}
irb(main):027:0> products
=> {554=>{}, 968=>{}, 665=>{}, 181=>{}}
Duke
  • 3,226
  • 1
  • 18
  • 23
0

Notice that the last statement in your method is the while loop, which will not execute if products is empty. Hence function returns nil.

Try like this:

products = {}

def random_key(products)

  rand_key = rand(900) + 100

  while products.has_key?(rand_key)

    rand_key = rand(900) + 100

  end

  rand_key

end

puts random_key(products)

Note however, that this has a potential of getting into an infinite loop once all numbers from 100 to 999 are in products

Mchl
  • 61,444
  • 9
  • 118
  • 120
  • Please upvote if you like it, but I think Marc Talbot's answer http://stackoverflow.com/a/9458016/402253 is the one worth accepting. – Mchl Feb 26 '12 at 23:02
0

Your function returns the while expression which is always nil. You should return the number instead:

def random_key(products)
  rand_key = rand(900) + 100
  while products.has_key?(rand_key)
    rand_key = rand(900) + 100
  end
  rand_key
end

Note that you can remove duplication by placing "while" after key generation:

def random_key(products)
  begin
    rand_key = rand(900) + 100
  end while products.has_key?(rand_key)
  rand_key
end

And you can omit begin end for a single expression

def random_key(products)
  rand_key = rand(900) + 100 while products.has_key?(rand_key)
  rand_key
end
Simon Perepelitsa
  • 20,350
  • 8
  • 55
  • 74