javascript - 在 Javascript 中比较两个对象数组与文字值的更快方法

标签 javascript algorithm lodash

  1. Array of Objects with Literal Values 的意思是,它是一个数组,它的每个元素都是一个对象,而这样的对象的值都是文字(所以它不会'不是嵌套对象、对象内部数组等),例如,它可以是:
[ { name: 'Bob', age: 20, isMale: true }, { name: 'Alice', age: 19, isMale: false}, ... ]
  1. Compare的意思是,我们需要区分addedremoved元素,例如:
const original = [ { name: 'Bob', age: 20, isMale: true }, { name: 'Alice', age: 19, isMale: false} ];
const modified = [ { name: 'Alice', age: 19, isMale: false}, { name: 'Jay', age: 21, isMale: true } ];

// then added = [{ name: 'Jay', age: 21, isMale: true }]
// and removed = [{ name: 'Bob', age: 20, isMale: true }]

我的方法:使用 lodash 的 differenceWithisEqual 来实现,例如:

const original = [ { name: 'Bob', age: 20, isMale: true }, { name: 'Alice', age: 19, isMale: false} ];
const modified = [ { name: 'Alice', age: 19, isMale: false}, { name: 'Jay', age: 21, isMale: true } ];

const removed = _.differenceWith(original, modified, _.isEqual);
const added = _.differenceWith(modified, original, _.isEqual);

^ 但是,它不够快!! 我有两个数组的样本,每个数组包含 10K+ 个对象,而每个对象都有 3 个具有 lietal 值的属性。像这样:

[{lat: 123.321, long: 234.432, radius: 100}, ....]         // 10K+ elements

我自己测试过,使用我的方法会花费:

  1. ~10 秒完成 <= 太慢
  2. 浏览器会因为繁重的计算而死机 <= 主要问题!

现在的问题是,您能否提供一种更快、更优雅的方法来比较此类样本?

我的一个猜测是我可以通过将 isEqual 替换为其他内容来改进,但不确定在这种情况下是否有帮助。

最佳答案

将每个对象与每个对象进行比较将导致 O(n^2) 问题,正如您所注意到的那样,复杂性增长非常快,然后是 10k 个对象(这在计算机世界中并不多) 几乎无法处理。

然而,有更简单的方法来完成这个。

预处理

  1. 按名称对两个数组进行排序,这需要 O(n*log(n))
  2. 0 开始为每个数组设置两个索引,我们称它为 ij

处理

  1. 比较 original[i]modified[j]
  2. 中的名称
  3. 如果相同,就是i++j++
  4. 如果不同,则在字符串比较中检查哪个“更低”(比如 Bob 比 Cathrine 低,因为它以 B 开头)
  5. 如果original[i]较低,则将其添加到removedi++
  6. 如果modified[j]较低,则将其添加到addedj++
  7. 重复直到处理完两个数组

最昂贵的部分是排序,其他一切都在 O(n) 时间内完成,因此整体复杂度将为 O(n*log(n))即使对于数百万个项目,这也足够了。

注意:如果您还需要比较年龄或性别,而不仅仅是姓名,则需要更新以上内容,按多个字段排序,然后按多个字段进行比较)

关于javascript - 在 Javascript 中比较两个对象数组与文字值的更快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58341767/

相关文章:

algorithm - 根据元素的特定属性的计数评估指示一组元素状态的分数

c# - 计算 X 位掩码的最快方法?

javascript - Lodash 性能因 _.uniqWith 删除重复对象而受到影响

javascript - 当用户单击缩略图时,我希望在 html 中弹出该图像

c++ - 对数字进行分组 C++

javascript - 与路由提供程序一起使用时,Angular JS ng-grid 不会填充数据

javascript - lodash/fp _.extend 不会像在 lodash 中那样改变第一个参数

javascript - 根据另一个数组对对象数组进行排序

JavaScript 对象快捷方式

javascript - 打印从根到具有多个子节点的树中给定节点的路径