2009-03-05 4 views
2

J'ai l'impression d'utiliser Ruby à tort: ​​Je veux générer toutes les correspondances possibles pour l'expression rationnelle Je ne peux pas utiliser succ car "999".succ => "1000" et "zZz".succ => "aaAa". Je vais avoir du mal à utiliser des plages parce que je ne peux pas sembler union (0..9), ('A'..'Z'), ('a'..'z')Générer une plage différente dans Ruby c'est-à-dire tout possible/[0-9A-Za-z] {3}/

J'é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 2 fois:

est-il un moyen moins laid, et est-il un moyen où alphaNumericX3 pourrait être défini à partir des paramètres (alphaNumeric, 3)? PS Je suis conscient que je pourrais définir une nouvelle classe pour la gamme. Mais ce n'est certainement pas plus court. Si vous pouvez faire ce bloc suivant plus court et plus clair que le bloc ci-dessus, s'il vous plaît faire:

class AlphaNum 
    include Comparable 
    attr :length 
    def initialize(s) 
    @a=s.chars.to_a 
    @[email protected] 
    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} 

Répondre

5

Utilisation 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('') } 
+0

ouais c'est assez accrocheurs aussi. – dlamblin

+0

vaut-il la peine d'utiliser ('0' .. '9'). To_a pour assurer toutes les chaînes à un seul caractère? –

+0

Ce n'est pas strictement nécessaire, mais cela ajoute de la cohérence. Edité, merci! –

0
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' 
Questions connexes