在迭代两个不同的数组时,我有一个严格基于性能的问题。
我的第一个数组按以下方式组成,对象由{id,number}
组成var arr1 = [{id: 1, number: 7}, {id: 2, number: 5}];
我的第二个数组由相同的id字段和字符串值
组成var arr2 = [{id: 2, string: 'foo'}, {id: 1, string: 'bar'}];
我的问题是,我需要将第一个数组中的id与第二个数组中的id匹配。我用以下方式编写了代码。
arr1.forEach(function(x){
arr2.forEach(function(y){
if(condition){
Do something...
}
});
});
在没有两个forEach循环的情况下,是否有更快/更有效的方法来迭代数组?或者该配置是比较所有值的最佳方法?
我写的代码工作并没有问题,但我不禁想到有一个更快(表现明智)的方法或在这里做同样事情的方法......
感谢您对此有任何见解!
答案 0 :(得分:0)
如果您希望语法更好,可以使用for...of
循环,但.forEach
是一个同步函数,是完全循环遍历数组的最快方法。此外,break
不能为for...of
d,因此使用.filter
可以让您在某些条件成功后停止迭代。
如果您尝试在阵列中查找特定的一组项目,则可能需要使用.map
,.find
,.some
,.every
,或{{1}}
答案 1 :(得分:-1)
使用本机for..loop
可以更快地生成相同的结果,因为forEach
方法只是相同的实现,但对于数组。如果您更喜欢速度超过表现力,请转到for..loop
查看此perf
答案 2 :(得分:-1)
快速搜索是将较大的数组减少为对象。然后你可以通过id来引用它。
我不知道你的if
语句中有什么条件,但我们假设我们要合并两个数组,那么它可能是这样的:
const arr1 = [{id: 1, number: 7}, {id: 2, number: 5}]
const arr2 = [{id: 2, string: `foo`}, {id: 1, string: `bar`}]
const list = arr1.reduce((all, next) => {
all[next.id] = next
return all
}, {})
const merged = arr2.map(el => list[el.id] ? {...el, ...list[el.id]} : el)
console.log(merged)
总迭代次数等于arr1.length + arr2.length
<强>更新强>
我不知道为什么会得到弊端,但提供的解决方案正在运行(至少快100倍),您可以通过运行基准来检查它:
const arr1 = []
for (let id = 0; id <= 100000; id++) {
const number = Math.round(Math.random() * 100);
arr1.push({ id, number })
}
const arr2 = []
for (let id = 1000; id > 0; id--) {
const string = id % 2 === 0 ? `foo_${id}` : `bar_${id}`
arr2.push({ id, string })
}
// Nested loops
console.time(`nestedLoops`)
const merged = []
arr2.forEach(x => {
arr1.forEach(y => {
if (x.id === y.id) {
merged.push({
id: x.id,
string: x.string,
number: y.number,
});
}
});
});
console.timeEnd(`nestedLoops`)
// Array to object then a loop
console.time(`array2object`)
const merged2 = []
const list = arr1.reduce((all, next) => {
all[next.id] = next;
return all;
}, {});
arr2.forEach(x => list[x.id] &&
merged2.push({
id: x.id,
string: x.string,
number: list[x.id].number
})
);
console.timeEnd(`array2object`)
答案 3 :(得分:-1)
实际上,您的代码以 O(n^2)
复杂度运行。
你能做的是:
arr1
arr2
和mergesort
进行排序
在这种方法中,您将获得O(n*logn + n*logn + n)
,从而产生 O(n*logn)
。
答案 4 :(得分:-1)
由于id属性应该是唯一的,为什么不利用这样的原生javascript对象:
var objects1 = {
id_1: {number: 7},
id_2: {number: 5}
};
var objects2 = {
id_2: {string: 'foo'},
id_1: {string: 'bar'}
};
console.log(objects1.id_1.number + ' | ' + objects2.id_1.string);
我认为这是最快的方法。
答案 5 :(得分:-1)
我建议您不要关心这一点,直到遇到性能问题
如果遇到性能问题:
注意
== UPDATE ==
测试结果: