Question

I want to combine two different ranges in rails into a single array. Is there any short method for the same?

I am writing code to generate random alpha-numeric strings.

Right now I have:

('a'..'z').to_a.shuffle.first(16).join

I have also tried something like this (which did not work):

('a'..'z').to_a.push('0'..'9').shuffle.first(16).join
Was it helpful?

Solution

I have a nicer method: use the splat operator!

[*'0'..'9', *'a'..'z', *'A'..'Z'].sample(16).join

OTHER TIPS

More elegant way:

['a'..'z', '0'..'9'].flat_map(&:to_a).sample(16).join

Try this:

('a'..'z').to_a.push(*('0'..'9').to_a).shuffle.first(16).join

Or try this:

('a'..'z').to_a.concat(('0'..'9').to_a).shuffle.first(16).join

The problem with the accepted .sample solutions is that they never repeat the same characters when generating a string.

> (0..9).to_a.sample(10).join
=> "0463287195"
# note you will never see the same number twice in the string
> (0..9).to_a.sample(15).join
=> "1704286395"
# we have exhausted the input range and only get back 10 characters

If this is an issue, you could sample a number of times:

> Array.new(10) { (0..9).to_a.sample }.join
=> "2540730755"

As for the .shuffle approaches, they are nice but could become computationally expensive for large input arrays.

Probably the easiest/best method for generating a short random string is to use the SecureRandom module:

> require 'securerandom'
=> true
> SecureRandom.hex(10)
=> "1eaefe7829b3919b385a"

You can use map to merge Ranges into an array such as

[ 'A'..'Z', 'a'..'z', '0'..'9' ].map { |r| Array(r) }.inject( :+ )

So in your example it would be

['a'..'z','0'..'9'].map{|r|Array(r)}.inject(:+).shuffle.first(16).join
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top