Gerar uma gama diferente em Ruby isto é, todos os possíveis / [0-9A-Za-z] {3} /
Pergunta
Eu sinto que estou usando Ruby da maneira errada aqui: Eu quero gerar todos os jogos possíveis para a expressão regular /[0-9A-Za-z]{3}/
Eu não posso usar succ
porque "999".succ => "1000"
e "zZz".succ => "aaAa"
.
Estou tendo problemas para usar faixas porque eu não consigo (0..9), ('A'..'Z'), ('a'..'z')
união
Então, eu escrevi:
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}
A minha pergunta é 2 vezes:
Existe uma maneira menos feio, e se existe uma maneira onde alphaNumericX3
poderia ser definida a partir do (alphaNumeric, 3)
parâmetros?
PS Estou ciente de que eu poderia definir uma nova classe de gama. Mas isso definitivamente não mais curto. Se você pode fazer isso no próximo bloco mais curto e mais claro do que o bloco acima, por favor:
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}
Solução
Use Array#product
:
alpha_numerics = ('0'..'9').to_a + ('a'..'z').to_a + ('A'..'Z').to_a
alpha_numerics
.product(alpha_numerics, alpha_numerics)
.map { |triplet| triplet.join('') }
Outras dicas
class String
def nextify
case self
when '9' then 'A'
when 'Z' then 'a'
when 'z' then '0'
else self.succ
end
end
end
class AlphaNum
def initialize(string)
@string = string
end
def succ
@string.split(//).inject("") { |s,n| s << n.nextify }
end
def method_missing(*args, &block)
@string.send(*args, &block)
end
end
a = AlphaNum.new("999")
puts a.succ #=> 'AAA'