2009-03-05 4 views
2

Ich habe das Gefühl, dass ich Ruby falsch verwende: Ich möchte alle möglichen Übereinstimmungen für den regulären Ausdruck erzeugen /[0-9A-Za-z]{3}/Generiere einen anderen Bereich in Ruby, dh alles möglich/[0-9A-Za-z] {3}/

Ich kann succ nicht verwenden, weil "999".succ => "1000" und "zZz".succ => "aaAa". Ich habe Probleme Bereiche verwenden, weil ich nicht zur Vereinigung scheinen (0..9), ('A'..'Z'), ('a'..'z')

Also schrieb ich:

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} 

Meine Frage ist 2-fach:

Gibt es eine weniger hässliche Art und Weise, und Gibt es einen Weg, wo alphaNumericX3 aus den Parametern (alphaNumeric, 3) definiert werden könnte?

PS Ich bin mir bewusst, dass ich eine neue Klasse für die Reichweite definieren könnte. Aber das ist definitiv nicht kürzer. Wenn Sie diesen nächsten Block kürzer und klarer als der obige Block machen können, bitte tun:

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} 

Antwort

5

Verwendung 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

ja das ist auch ziemlich bissig. – dlamblin

+0

ist es vielleicht sinnvoll, ('0' .. '9'). To_a zu verwenden, um alle Einzelzeichenfolgen sicherzustellen? –

+0

Es ist nicht unbedingt notwendig, aber es fügt Konsistenz hinzu. Bearbeitet, danke! –

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'