获取 Javascript 中尚未使用的较低整数 id

Get the lower integer id not already used in Javascript

本文关键字:整数 id 未使用 Javascript 获取      更新时间:2023-09-26

我有一个由整数ID定义的JS对象列表。

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

我实现了一个函数来从我的列表中删除一个元素:

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

我的问题是我需要创建一个函数来在我的列表中添加一个 id 尚未使用的新项目(例如列表中不存在的下正整数)。

我试图做这样的事情,但当我删除对象 0(例如)时它不起作用。

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

我该怎么做?

编辑 1

根据您的回答,我认为就性能而言,最好的解决方案是只使用 topId,当我在列表中添加新对象时,该 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);
};

如果你删除实例 0 并且下一个 addObject 是 0,你必须执行以下操作:

  • 保留一个列表 [初始空],并删除每个 ID。当您需要添加新的时,请选择较短的,从列表中添加和删除。
  • 还要保留一个添加了最大 ID 的 var。如果上一个列表为空,则将 +1 添加到 var 并使用该 id 添加对象

使用正确的结构。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"

然后正常的索引操作来获取/设置/删除。

如果您使用该函数,那么您的数据结构上有一个不变的(保证),即您不会两次使用相同的 ID。

你需要一个函数来查找第一个空闲号码:

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;
    }
}

在 Javascript 中,MaxInt 是9007199254740992。为什么不继续递增呢?

你可以而且可能应该使用这样的数组:

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

要添加对象,请参阅:如何将某些内容附加到数组中?

要查找值:var index = objects.type.indexOf('foo');

要查找第一个空字段var index = objects.type.indexOf('');,您可以使用该字段查找要添加的元素(如果索引为 -1,请使用 objects.type.length),如果您通过将元素设置为"来"删除"元素或......除非您有特定原因将"ID"保持静态(在本例中为数组索引),否则请删除该元素并仅在末尾附加新元素

要删除元素,请参阅:如何在 JavaScript 中从数组中删除特定元素?这将允许您只推送/附加下一个数据。

如果您需要一个包含空字段的新对象数组来填充,因为您要跟踪新数据:

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

如果你到了你的对象包含多个数组的地步,你可能想要创建用于插入/添加和删除/删除的函数,这样你就不会对 1 而不是另一个执行操作。

一切都已经内置了(可能已经读得很快),你不需要为你非常酷的对象类型重新发明构造函数。