检查数组中条件的有效方法

时间:2013-02-14 07:10:29

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

我有一个客户端模型,在下面的实例变量中,我正在收集所有标识符。

@all_clients = Client.all.collect{|a| a.identifier}

这将返回["client123", "client234", "client567", "client789"]

此外,我有一个变量@create_id =“client123”,我正在通过@all_clients.include? @create_id检查集合中是否存在@ create_id的值 如果返回true,我将像这样添加“_1”:@create_id<<"_1"并保存@create_id以后通过该ID创建客户端。

我再次检查集合中是否存在最新的@create_id“client123_1”,如果是,我添加_2并进一步检查并最终保存。 这是我所知道的最糟糕的检查方式,因为我是编程新手。

有人可以帮助我找到一种有效的方法来做到这一点。

  

我需要做的就是首先检查我的变量是否为   如果不存在,则将_1附加到它,然后检查string_1是否为   已经存在并进一步向_2或_3进一步移动。该   下划线和整数保持增量取决于检查   集合。

提前致谢

1 个答案:

答案 0 :(得分:2)

您可以将AR查询限制为仅包含与@create_id

前缀匹配的记录
clients=Client.arel_table
matching_clients = Client.where( clients[:identifier].matches( "#{@create_id}%" ) )

如果matching_clients为空,则没有具有该标识符前缀的客户端。除此以外 现在你可以提取整数后缀片段并找出下一个可用的id是什么。

last_suffix = matching_clients.
  map(&:identifier).
  map { |s| (s.split('_',2)[1] || 0).to_i }.
  max

如果索引支持标识符字段,则应该相当有效。

如果你的方案使用了一个后缀格式,允许对后缀进行正确的词法排序(例如,总是将后缀填充到固定的宽度),那么你可以通过索引将更多的工作推送到数据库中。为匹配的最大标识符。

请注意,如果您有多个并发进程可能需要创建新的唯一标识符,则整个方法都会受到竞争条件的影响。如果您的db模式在clients.identifier上具有唯一索引(它也支持查询效率),那么当您尝试使用您制造的新标识符保存记录时,db将抛出唯一性约束错误,在这种情况下,您可以继续尝试,重新选择并推导新的候选标识符,直到你再次成功。