【发布时间】:2025-12-10 22:30:01
【问题描述】:
需要一个算法的帮助,该算法采用两个数组并导致它们之间保持相同顺序的特定比较:
- 如果 _ID 在现有但 _ID 不在覆盖器中,则不要在结果中包含元素
- 如果 _ID 在覆盖中但 _ID 不存在,则将元素添加到 RESULT
- 如果 _ID 存在于现有和覆盖器中,则将具有 _ID 版本/实例的元素从现有添加到结果中
大写字母代表引用_ID v# 表示版本/实例引用_ID
1.
现有:[Av1 Bv1 Cv1 Ev1 Fv1 Gv1]
覆盖:[Bv2 Dv1 Fv2 Hv1 Jv1]
结果:[ Bv1 Dv1 Fv1 Hv1 Jv1 ]
2.
现有:[Bv1 Cv1 Ev1 Fv1 Gv1]
覆盖:[Av1 Bv2 Dv1 Fv2 Hv1 Jv1]
结果:[Av1 Bv1 Dv1 Fv1 Hv1 Jv1]
3.
现有:[Av1 Bv1 Cv1 Ev1 Fv1 Gv1]
覆盖:[Av2 Bv2 Dv1 Fv2 Hv1 Jv1]
结果:[Av1 Bv1 Dv1 Fv1 Hv1 Jv1]
4.
现有:[Cv1 Dv1 Ev1]
覆盖:[Av1 Bv1 Dv2 Fv1 Hv1 Jv1]
结果:[Av1 Bv1 Dv1 Fv1 Hv1 Jv1]
5.
现有:[Av1 Bv1 Cv1 Ev1 Fv1 Gv1]
覆盖:[Dv1]
结果:[Dv1]
我正在寻找一个 log(n) 函数,它可以一次性执行此突变操作(可能具有现有和覆盖器的枢轴索引,但我不确定)。
不想使用 indexOf。
这是我使用缩尾技术的 log(n^2) 解决方案:
let eIndx = 0,
existing = [ Av1, Bv1, Cv1, Ev1, Fv1, Gv1 ],
overwriter = [ Bv2, Dv1, Fv2, Hv1, Jv1 ];
overwriter.map( element => {
while( element._ID !== existing[ eIndx ]._ID &&
eIndx !== existing.length ) {
delete existing[ eIndx ];
++eIndx;
}
return eIndx !== existing.length ? existing[ eIndx ] : element;
});
如果现有的 _ID 都没有在覆盖器中,则此解决方案最慢。
我不确定是否应该遍历现有数组或覆盖器数组。
在我转述这篇文章的扩展(更复杂)解决方案中,我遍历了覆盖器,并且我有一个哈希字典来引用将来是否已经存在 _ID/version 组合(后来的索引尚未要迭代)的数组。我不能再使用那个全局字典,我想弄清楚我是否需要为每个数组实例制作一个本地字典,或者是否有一种方法我不需要字典而只使用枢轴进行比较。我在 log(n) 解决方案中看到的一个问题是,它不知道覆盖器的第一个元素是否是新的 _ID,而无需遍历所有现有数组。
我主要是在寻找尽可能快的东西
非常感谢您能分享的帮助。
【问题讨论】:
标签: javascript arrays masking mutation