Erzeugen einen anderen Bereich in Ruby d.h. alle möglichen / [0-9A-Za-z] {3} /

StackOverflow https://stackoverflow.com/questions/613697

  •  03-07-2019
  •  | 
  •  

Frage

Ich fühle mich wie ich bin mit Ruby den falschen Weg hier: ich alle möglichen Übereinstimmungen für den regulären Ausdruck /[0-9A-Za-z]{3}/ generieren möchten

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

So 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 ist es eine Möglichkeit, wo alphaNumericX3 aus dem Parameter (alphaNumeric, 3) definiert werden?

PS Ich bin mir bewusst, dass ich eine neue Klasse für Bereich 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, gehen Sie bitte:

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}
War es hilfreich?

Lösung

Verwenden Sie 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('') }

Andere Tipps

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'
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top