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

4 回答 4

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
于 2013-04-24T01:35:54.613 回答
1

Sam 的回答看起来正是您所要求的,但这里有另一种可能有用的方式来查看您的问题:

将您的字符串视为以 26 为基数的数字,其中数字由“a”..“z”表示。这种方式与您要求的方式之间的唯一区别是第一个两位数(错误,两个字母的字符串)将是ba而不是aa(假设您从a = 0,b = 1 开始计数,等)并且您不会生成任何以 a 开头字符串(第一个除外),原因与您不写以 0 开头的整数(第一个除外)相同的原因。

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

于 2013-04-24T03:17:43.617 回答
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
于 2013-04-26T03:43:56.863 回答
0

您正在寻找Kleene 明星。未经测试,但似乎RLTK gem 可以为您提供这样的功能。

于 2013-04-24T01:28:07.130 回答