I have a nicer method: use the splat operator!
[*'0'..'9', *'a'..'z', *'A'..'Z'].sample(16).join
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
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