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)
1
  • Note the requirements for non-repeated numbers. That said, you really need a shuffle algorithm. Commented May 18, 2012 at 13:57

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

Please upvote if you like it, but I think Marc Talbot's answer stackoverflow.com/a/9458016/402253 is the one worth accepting.
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

Comments

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=>{}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.