【问题标题】:Ruby : Finding lowest free ID in an ID arrayRuby:在 ID 数组中查找最低的空闲 ID
【发布时间】:2012-02-06 08:13:21
【问题描述】:

我有一个从 1 到 4000 的不同 ID 的数组。我需要在数据库中添加一些元素,其 ID 将进入该数组。由于可能的最大 ID 是 4000(在我的情况下并没有那么多),我希望能够找到可以用于新元素的最低未使用 ID。

我会知道如何在 C++ 中做到这一点,但由于我是 Ruby 的新手,我正在寻求帮助。在 C++ 中,我会编写一个循环来检查 array[i] == array[i+1] - 1。如果不是这样,那么新的 id 将是 array[i] + 1。

我只是不知道如何在 Ruby 中编写它。

【问题讨论】:

  • 这导致 id 1 指的是 1 月份的苹果,但可能是 2 月份的香蕉。正常程序是让数据库管理 id 列。您最多有 4000 的事实使它看起来像 id 有意义(例如 0-4000 是食品类别,4001-5000 是玩具) - 一个坏主意。

标签: ruby arrays loops arraylist


【解决方案1】:

使用范围,您可以找到不属于数组的第一个元素:

array = [1,2,3,5,6]
(1..4000).find { |i| !array.include?(i) }
# => 4

【讨论】:

  • 这可能效率很低,因为包含?方法可以被调用数千次(它的二次复杂度)
  • 是的,第一个可用的 id 越高,速度肯定越慢(当它为 3999 时,会有明显的延迟)。其他答案解决了这个问题。
【解决方案2】:
array = [1, 2, 3, 5, 6]
(1..4000).to_a.-(array).min

【讨论】:

  • +1 @sawa,非常简洁明了。也应该跑得很快。
  • 这确实非常非常聪明
  • 我用过这个,效果很好,非常感谢您的帮助!
【解决方案3】:
def first_unused_id(ids)
  index = ids.each_index.find{|i| ids[i] + 1 != ids[i+1] }
  ids[index] + 1
end

一些解释:

  • each_index 会将数组转换为 Enumerator,并提供数组索引。
  • find 将返回第一个从传递给它的块返回 true 的元素。

【讨论】:

    【解决方案4】:

    这个怎么样:

    (1..4000).find { |i| array[i-1] != i }
    

    类似于 Dylan 的回答,但在这种情况下,它只是检查数组的第 [n-1] 个成员是否为 n。如果不是,则该索引是“打开的”并被返回。此解决方案只需要对每个索引进行一次检查,而不是 4000...

    所以

    array = [1,2,3,5,6]
    

    这将找到 array[4-1] != 4(因为 array[3] = 5)并返回 4 作为第一个可用的 id。

    (这需要一个排序的索引数组,但到目前为止已经假设)

    【讨论】:

    • 那会差一 - array[0] 将是 1,而不是 0;它应该是array[i-1]。此外,您发布的代码根本无法正常工作,因为!array[i] 将始终为false。应该是array[i-1] != i
    【解决方案5】:
    array = [1, 2, 3, 5, 6]
    
    def lowest_unused(ids)
      ids.find { |e| ids.index(e) + 1 != e } - 1
    end
    
    p lowest_unused(array) # 4
    

    【讨论】:

    • 类似于 Jakub Hampl 的回答,但更简单
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2021-01-16
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多