【问题标题】:Fast find for indices by ID按 ID 快速查找索引
【发布时间】:2016-02-09 07:26:29
【问题描述】:

我有一百万个对象,每个对象都有一个唯一的 ID - 编号。 每个简化的对象都包含名称

它们的对象正在被添加到数组中。

我在这个数组中添加和删除对象。

为了移除我有id的对象,然后需要在数组中找到索引并拼接出来。

在我的情况下,我有分配对象并且可以分配删除操作。所以如果我有 1000 次删除。并且所有这些对象的 id 都存储在数组的末尾,然后我将遍历所有 100 万个对象,直到找到它们为止。

添加后将索引存储在对象中并不好,因为每次删除我都需要更新删除后存储的所有对象的索引。 例如,删除前 1000 个将导致更新其余 1M-1000 个项目索引。

我的问题是,我的问题的最佳解决方案是什么?

-- 更新--

例如:添加 1M 个对象后我的平面数组是这样的

[ obj1, obj2, obj3, .... obj1000000 ]

我现在想删除对象 obj1000000。用于查找该对象的索引 被插入到我需要遍历所有数组(或直到我找到该项目)并将当前项目 id 与我的 obj1000000 id 进行比较,并在找到时从循环中中断。然后通过它的索引删除该项目。

如果我将每个对象的索引在添加到数组后存储在对象本身中,我将不得不在删除一个对象索引后更新其余的对象索引。

例如:obj1 将包含属性index=0obj2 将包含index=1 等等。要删除obj5,我只需获取其属性index,即4,然后将其删除。但现在 obj6 具有 index=5 不正确。应该是4。并且 obj7 应该是 5 等等。所以必须更新。

我的SmartArray 拥有一个以某种大小创建的 TypedArray。如果需要,我会花费它。当 push 被调用时。我只是在最后一项 this._array[this.length++] = value; 中设置值(当然检查是否扩展数组)

SmartArray.prototype.getArray = function () {
    return this._array.subarray(0, this.length);
}

SmartArray.prototype.splice = function (index, removeCount) {

    if (index + removeCount < this.length) {
       var sub = this._array.subarray(index + removeCount, this.length);
       this._array.set(sub, index);
    } else {
        removeCount = this.length - index;
    }

    this.length -= removeCount;
}

它工作得非常快,subarray 不会创建新数组。 set 的工作速度也非常快。

【问题讨论】:

  • 你为什么要使用数组?拼接数组与线性搜索一样昂贵。
  • 我正在使用 web gl 进行绘图,这需要平面数组。我开发了一个智能类型数组,实际上并没有在每个拼接处创建新数组..它工作正常。瓶颈是搜索要删除的索引
  • splice 确实没有创建新数组,但它确实需要在删除的项目之后重新排序所有索引......或者你使用稀疏数组?请向我们展示您的智能类型数组实现。
  • 制作一个id映射到索引?
  • 我不明白你的意思是 ids 存储在数组的末尾,或者你的意思是把索引存储在对象中不好。

标签: javascript arrays algorithm performance


【解决方案1】:

这个问题的标准解决方案是

  • 平衡(二叉)树,
  • 哈希表。

他们平均每次搜索/插入/删除分别进行 O(Log(N)) 和 O(1) 次操作。

两者都可以在数组中实现。您可以通过网络搜索找到它们的许多版本。

【讨论】:

  • 你的意思是每次删除我都会重新索引所有的树?因为当删除完成时,我需要更新改变树的叶子的值
  • 没有理由不使用 JavaScript 中可用的内置数据结构。
  • @RazizaO:你应该阅读二叉树和哈希表来了解它们是如何工作的。
  • ... 然后花点时间考虑一下简单的对象属性查找和 ES2015 Map 机制已经使用最佳实践的键查找数据结构实现了。
  • 我想我真的想错了,或者你们没有正确理解我。如果我通过键保存在哈希表/二叉树/映射中,值应该是什么?如果您的意思是保存索引,那么从哈希表/二叉树/映射中删除该项目将比删除后添加的所有项目偏移 1. 依此类推.. 如果我完全关闭,请引导我了解你的想法
猜你喜欢
  • 1970-01-01
  • 2016-01-14
  • 1970-01-01
  • 2016-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多