Genera un intervallo diverso in Ruby, ovvero tutto il possibile / [0-9A-Za-z] {3} /
Domanda
Sento che sto usando Ruby nel modo sbagliato qui: voglio generare tutte le possibili corrispondenze per l'espressione regolare / [0-9A-Za-z] {3} /
Non riesco a usare succ
perché " 999 " .succ = > " 1000 "
e " zZz " .succ = > & Quot; AAAA "
.
Sto riscontrando problemi nell'uso degli intervalli perché non riesco a unire (0..9), ('A' .. 'Z'), ('a' .. 'z')
Quindi ho scritto:
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}
La mia domanda è 2 volte:
C'è un modo meno brutto e c'è un modo in cui alphaNumericX3
potrebbe essere definito dai parametri (alphaNumeric, 3)
?
PS Sono consapevole che potrei definire una nuova classe per intervallo. Ma questo non è sicuramente più breve. Se riesci a rendere questo blocco successivo più breve e più chiaro del blocco precedente, ti preghiamo di fare:
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}
Soluzione
Usa 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('') }
Altri suggerimenti
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'