2013-10-23 19 views
0

我有一個由整數ID定義的JS對象列表。獲取尚未在Javascript中使用的較低整數ID

objects = [{ 
    id: 0, 
    type: 'null' 
}, { 
    id: 1, 
    type: 'foo' 
}, { 
    id: 2, 
    type: 'bar' 
}]; 

我實現了一個功能,從我的列表中刪除一個元素:

removeObject = function(o){ 
    objects.splice(objects.indexOf(o), 1); 
} 

我的問題是,我需要建立一個功能到我的列表中添加新項與ID尚未使用(例如列表中不存在的較低正整數)。

我試圖做這樣的事情,但當我刪除對象0(例如)它不起作用。

​​

我該怎麼做?

編輯1

根據您的回答,我認爲在性能方面最好的解決方法就是使用topId,當我在我的列表中添加一個新的對象,總是遞增。

但這並不能滿足我的要求。其實我認爲@X-Pippes的反應可能會很好。

我應該做些事情那樣:

objects = [{ 
    id: 0, 
    type: 'null' 
}, { 
    id: 1, 
    type: 'foo' 
}, { 
    id: 2, 
    type: 'bar' 
}]; 

// Init available ids list with the default value 
availableIds = [objects.length]; 

removeObject = function(o){ 
    // Remove the object from the list 
    objects.splice(objects.indexOf(o), 1); 
    // Add its id to the available ids list 
    availableIds.push(o.id); 
} 

addObject = function(type){ 
    // Get lower id available 
    var newId = Math.min.apply(Math,availableIds); 
    // Push the new object with the id retrieved 
    objects.push({ 
     id: newId, 
     type: type 
    }); 
    // Remove used id from the available ids list 
    availableIds.splice(availableIds.indexOf(newId), 1); 
    // Add a default id if available list is empty 
    if(availableIds.length < 1) availableIds.push(objects.length); 
}; 
+4

如果您刪除實例0,則下一個addObject應與id = 0? –

+3

爲什麼不簡單地跟蹤上次使用的ID並增量?爲什麼使用數組而不是地圖? –

+0

正在使用數組並跟蹤移動索引時刪除項目,而不是每個項目的id,而不是問題?對於最好的解決方案,數組,散列表等,它將取決於項目從列表中被逐出的頻率以及您需要的其他操作。 –

回答

1

使用正確的結構。一個JavaScript object將完成這項工作。它保證你只能得到一個關鍵項,你可以通過鍵來查找和刪除可能的O(1)ish。沒有意義,試圖以低效的方式重新實現它,這將是O(n)查找。

var structure = { 
    objects : {}, 
    topId : 0 
} 

structure.add = function(item) { 
    var id = this.topId ++; 

    structure.objects[id] = item; 
} 

structure.add("thing") 
structure.add("other thing") 
structure.add("another thing") 

structure.objects 
>>> Object {0: "thing", 1: "other thing", 2: "another thing"} 

structure.objects[1] 
>> "other thing" 

然後正常的索引操作get/set/delete。

如果您使用該功能,那麼您的數據結構上有一個不變的(保證),您不會使用相同的ID兩次。

+3

這將如何解決尋找編號最小的「id」值來存儲新條目的問題? – Pointy

+0

看我的編輯。 (額外的字符) – Joe

+1

當你刪除structure.objects [1],並添加? OP希望下一個項目轉到structure.objects [1]而不是下一個最高索引。 –

1

如果刪除例如0,下一個ADDOBJECT是你必須做一些像0:

  • 保持列表[初始空]去掉每一個ID。當你需要添加一個新的,選擇較短的,添加和從列表中刪除。
  • 同時保留添加了最大ID的變量。如果前面的列表是空的,添加+1到var和ADDOBJECT與ID
0

您需要一個函數來找到第一個免費電話:

addObject = function(type){ 
    objects.push({ 
     id: firstOpenIndex(), 
     type: type 
    }); 
}; 

firstOpenIndex = function() { 
    for(var idx = 0; true; i++) { 
     var found = false; 
     for(var o in objects) { 
      if (objects[o].id == idx) { 
      found = true; 
      break; 
      } 
     } 
     if (!found) return idx; 
    } 
} 
+0

什麼是「開放」?像這樣的東西看起來是明顯的,微不足道的解決方案。如果沒有差距,則會導致O(n)最糟糕的時間。 –

+0

一個錯字---它應該是idx。我同意這是明顯/微不足道的,但這幾乎是OP要求的。如果您要通過最低數字填充第一個可用間隙,則需要O(n^2)。這可以通過一個不同的數據結構來提高效率,但是如果你想保持OP提出的要求則不會。 –

+0

其實從頭開始,這將是O(n^2)最差的情況。 –

0

在Javascript中MAXINT是9007199254740992爲什麼不只是繼續增加?

0

可以,而且也應該只使用像數組(S):

objects.type=['null','foo','bar'];

添加對象看: How to append something to an array?

找到一個值:var index = objects.type.indexOf('foo');

到找到第一個空字段var index = objects.type.indexOf('');,如果您通過se「刪除」一個元素,您可以使用它查找要添加的元素(如果index爲-1,則使用objects.type.length)將它設置爲「」或...除非你有保持「ID」爲靜態的特定原因(在這種情況下爲數組索引),否則刪除該元素並僅添加新元素到末尾

刪除元素: How do I remove a particular element from an array in JavaScript? 這將允許您只需按下/追加下一個數據。

,如果你需要用空字段一個新的對象數組來填充,因爲你得到新的數據跟蹤:

object.newField=new Array(objects.type.length);

如果你到了這個地步,你的對象包含多個陣列,你可能會想創建插入/添加和刪除/刪除功能,所以你不要對1進行操作,而不是對另一個進行操作。

所有內容都已經內置(讀取速度可能已經很快),並且您不需要爲非常酷的對象類型重新構造構造函數。

+0

找到第一個空字段將是O(N),可能會變得非常大(對於任何實現都爲真)。或者,如果您只想使用topId,您將以稀疏陣列中的'洞'爲單調增長。 – Joe

+0

@Joe - 但找到字段N將採取O(1),這通常比插入/刪除更普遍,這就是爲什麼我建議刪除(不只是刪除),然後添加新的元素,除非有一個_reason_保持稀疏,例如該id對應於稍後可能被恢復的客戶賬戶或某事。我在這裏做了一個比較的測試案例:http://jsperf.com/array-vs-object-performance/12 – technosaurus

+0

偉大的是,你做了一個性能比較,但查找只有一個操作,只有大約20%的差異。無論如何,沒有任何爭議的跡象表明,性能在任何情況下都可能微不足道, – Joe

相關問題