Rails循环通过'A..Z'以及更远?

时间:2013-04-24 01:21:29

标签: ruby-on-rails ruby-on-rails-3

我需要根据模型的start_date生成唯一名称。我有以下代码正在运行。但是,正如您所看到的,它只支持字母Z.有没有一种方法可以让它在Z之外工作,就像这个序列一样? A,B,C,...X,Y,Z,AA,AB,AC,AD,AE...AZ,BA,BB,BC...

  def generate_name
    ("A".."Z").each do |letter|
      random_token = start_date.strftime("%m%d%y") + letter
      break random_token unless Tour.where(name: random_token).exists?
    end
  end

4 个答案:

答案 0 :(得分:2)

def letters
  ('a'..'z').each { |i| yield i }
  letters do |i|
    ('a'..'z').each { |j| yield i+j }
  end
end

def generate_name
  letters do |letter|
    random_token = start_date.strftime("%m%d%y") + letter
    break random_token unless Tour.where(name: random_token).exists?
  end
end

答案 1 :(得分:1)

Sam的答案看起来就像你要求的那样,但这是另一种可能有用的方式来查看你的问题:

将您的字符串视为基数为26的数字,其中数字由'a'...'z'表示。这样做和你请求的方式之间的唯一区别是,前两位数字(错误,两个字母的字符串)将是 ba 而不是 aa (假设您开始使用 a = 0, b = 1等进行计数,并且您不会生成以 a 开头的任何字符串(除了第一个之外)出于同样的原因,你不要写出以0开头的整数(除了第一个)。

如果您很快计算出名称​​ dw 是您生成的第100个,那么这种方法是有用的。这也是将 hexavigesimal 这个词用于对话或至少用于文档的好方法。

答案 2 :(得分:1)

谢谢Sunxperous。

这有效:

  def generate_name
    ("A".."ZZZ").each do |letter|
      random_token = start_date.strftime("%m%d%y") + letter
      break random_token unless Tour.where(name: random_token).exists?
    end
  end

答案 3 :(得分:0)

您正在寻找Kleene star。未经测试,但似乎RLTK gem可以为您提供此类功能。