2013-10-23 55 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

相关问题