2012-01-09 68 views
3

我有一個數組,其ID從1到4000不等。我需要在數據庫中添加一些元素,並將ID放在該數組中。由於最大的ID可能是4000(這在我的情況中並不多),所以我希望能夠找到可用於我的新元素的最低未使用ID。Ruby:在ID數組中找到最低的空閒ID

我會知道如何在C++中做到這一點,但由於我在Ruby中很新,我正在尋求幫助。在C++中,我會寫一個循環,以至於我會檢查數組[i] ==數組[i + 1] - 1.如果不是這樣的話,那麼新的id將是數組[i] +1。

我有理由不知道如何在Ruby中編寫它。

非常感謝您的幫助。

+0

這將導致ID 1指的是蘋果在一月份,但也許香蕉在二月。正常的過程是讓數據庫管理id列。事實上,你最多有4000個,這使得它看起來像這個ID有一個含義(比如0-4000是類別食物,4001-5000是玩具) - 一個壞主意。 – steenslag 2012-01-09 20:41:45

回答

5
array = [1, 2, 3, 5, 6] 
(1..4000).to_a.-(array).min 
+0

+1 @sawa,非常好,簡潔。也應該很快運行。 – 2012-01-09 22:12:35

+0

@TheTinMan謝天曼。 – sawa 2012-01-09 22:27:26

+0

這確實非常非常聰明 – maprihoda 2012-01-09 23:25:00

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的第一個元素。
6

使用範圍,你可以找到,是不是你的陣列的一部分的第一個元素:

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

這可能是非常低效的,因爲包含?方法可以被稱爲許多次(這是二次複雜的) – maprihoda 2012-01-09 23:19:49

+0

是的,肯定有一些緩慢的第一個可用的ID越高(當它是3999,有一個明顯的延遲)。其他答案解決這個問題 – 2012-01-10 01:47:49

0

這個怎麼樣:

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

類似Dylan的答案,但在這情況下,它只是檢查數組的[n-1]個成員是否爲n。如果不是,該索引是「打開」並返回。此解決方案僅需要每索引,而不是4000一個校驗...

所以對於

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

這會發現,陣列[4-1]!= 4(因爲陣列[3] = 5),並返回4作爲第一個可用的ID。

(這需要指標的排序陣列但迄今假設)

+1

那會被一個 - 'array [0]'爲1,而不是0;它應該是'array [i-1]'。另外,你發佈的代碼根本不起作用,因爲'!array [i]'將永遠是'false'。它應該是'array [i-1]!= i' – 2012-01-09 20:41:36

+0

謝謝迪倫!編輯。 – elijah 2012-01-09 21:01:28

0
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 
+0

類似於Jakub Hampl的回答,但有點簡單 – maprihoda 2012-01-09 21:12:40