Générez une plage différente dans Ruby, c'est-à-dire tout possible / [0-9A-Za-z] {3} /
Question
J'ai l'impression que j'utilise Ruby de manière erronée: je souhaite générer toutes les correspondances possibles pour l'expression régulière / [0-9A-Za-z] {3} /
Je ne peux pas utiliser succ
car " 999 " .succ = > " 1000 "
et & z; & zzz " .succ = > "aaAa"
.
Je ne parviens pas à utiliser les plages car je n'arrive pas à associer (0..9), ('A' .. 'Z'), ('a' .. 'z')
J'ai donc écrit:
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}
Ma question est double:
Existe-t-il un moyen moins laid et un moyen de définir alphaNumericX3
à partir des paramètres (alphaNumeric, 3)
?
PS Je suis conscient que je pourrais définir une nouvelle classe pour range. Mais ce n'est définitivement pas plus court. Si vous pouvez rendre ce bloc suivant plus court et plus clair que le bloc ci-dessus, veuillez procéder comme suit:
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}
La solution
Utilisez Array # product
. a>:
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('') }
Autres conseils
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'