I feel like I’m using Ruby the wrong way here: I want to generate all possible matches for the regular expression /[0-9A-Za-z]{3}/
I can’t use succ because '999'.succ => '1000' and 'zZz'.succ => 'aaAa'. I’m having trouble using ranges because I can’t seem to union (0..9), ('A'..'Z'), ('a'..'z')
So I wrote:
def alphaNumeric #range and succ don't cut it for [0-9a-zA-Z] (0..9).each{|x|yield x.to_s} ('a'..'z').each{|x|yield x} ('A'..'Z').each{|x|yield x} end def alphaNumericX3 alphaNumeric{ |a| alphaNumeric{ |b| alphaNumeric{ |c| yield a+b+c } } } end alphaNumericX3.each{|x|p x}
My question is 2 fold:
Is there a less ugly way, and is there a way where alphaNumericX3 could be defined from the parameters (alphaNumeric, 3)?
PS I’m aware that I could define a new class for range. But thats definitly not shorter. If you can make this next block shorter and clearer than the above block, please do:
class AlphaNum include Comparable attr :length def initialize(s) @a=s.chars.to_a @length=@a.length end def to_s @a.to_s end def <=>(other) @a.to_s <=> other.to_s end def succ def inc(x,n) return AlphaNum.new('0'*(@length+1)) if x<0 case n[x] when '9' n[x]='A' when 'Z' n[x]='a' when 'z' n[x]='0' return inc(x-1,n) else n[x]=n[x].succ end return AlphaNum.new(n.to_s) end inc(@length-1,@a.clone) end end # (AlphaNum.new('000')..AlphaNum.new('zzz')).each{|x|p x} # === alphaNumericX3.each{|x|p x}
Use
Array#product: