[英]multiple array iteration javascript
I have a question strictly based in regards to performance while iterating through two different arrays. 我有一个严格的关于性能的问题,同时遍历两个不同的数组。
My first array is composed in the following way, objects consisting of an {id, number} 我的第一个数组是通过以下方式组成的,对象由{id,number}组成
var arr1 = [{id: 1, number: 7}, {id: 2, number: 5}];
My second array is composed of the same id field, and a string value 我的第二个数组由相同的id字段和一个字符串值组成
var arr2 = [{id: 2, string: 'foo'}, {id: 1, string: 'bar'}];
My question is this, I need to match the id's from the first array with the second array specifically in that order. 我的问题是,我需要按顺序将第一个数组的ID与第二个数组进行匹配。 I wrote my code in the following manner.
我以以下方式编写了代码。
arr1.forEach(function(x){
arr2.forEach(function(y){
if(condition){
Do something...
}
});
});
Is there a faster/more effective way to iterate through the arrays without two forEach loops? 有没有一种更快/更有效的方法来遍历数组而无需两个forEach循环? Or is that configuration the best method for comparing all the values?
还是该配置是比较所有值的最佳方法?
The code I wrote works and returns no problem, but I can't help thinking there's a faster (performance wise) method or means of doing the same thing here... 我编写的代码可以正常工作并且不会返回任何问题,但是我不禁想到这里有一种更快的(性能明智的)方法或方法可以做同样的事情...
Thanks for any and all insight in regards to this! 感谢您对此的任何见解!
You can use a for...of
loop if you like the syntax better, but .forEach
is a synchronous function and is the fastest way to completely loop through the arrays. 如果您更喜欢语法,则可以使用
for...of
循环,但是.forEach
是一个同步函数,是完全循环遍历数组的最快方法。 Also, .forEach
cannot be break
d so using a for...of
allows you to stop the iteration after some condition succeeds if you want. 另外,
.forEach
不能break
d,因此使用for...of
允许您在某些条件成功后停止迭代(如果需要)。
If you're trying to find a specific set of items from within the arrays, you may want to use .filter
, .map
, .find
, .some
, or .every
如果您尝试从数组中查找一组特定的项目,则可能需要使用
.filter
, .map
, .find
, .some
或.every
Well using the native for..loop
would produce the same results much faster since the forEach
method is just the same implementation but for arrays. 很好地使用本机的
for..loop
会更快地产生相同的结果,因为forEach
方法只是针对数组的相同实现。 If you prefer speed over expressiveness then go for the for..loop
如果您更喜欢速度而不是表现力,那就去
for..loop
🚀 The fast search would be if you reduce the larger arrays into object. search快速搜索将是将较大的数组缩小为对象。 And then you can refer to it by id.
然后您可以通过id引用它。
I don't have idea what condition you have in your if
statement, but assume we want to merge the two arrays, then it could be like this: 我不知道您的
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)
The total iteration would be equal to arr1.length + arr2.length
总迭代将等于
arr1.length + arr2.length
UPDATE 更新
I don't know why I get minuses, but the offered solution is working (at least 100 times faster), you can check it by running the benchmark 📈: 我不知道为什么会出现缺点,但是提供的解决方案有效(至少快100倍),您可以通过运行基准测试check进行检查:
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`)
Actually, your code runs in O(n^2)
complexity. 实际上,您的代码以
O(n^2)
复杂度运行。
What you can do is: 您可以做的是:
arr1
and arr2
using mergesort
mergesort
对arr1
和arr2
进行mergesort
In this approach you will get O(n*logn + n*logn + n)
, resulting in O(n*logn)
. 在这种方法中,您将获得
O(n*logn + n*logn + n)
,从而得出O(n*logn)
。
Since the id property is supposed to be unique, why not taking advantage of native javascript objects like this : 由于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);
I think this is the fastest way to do that . 我认为这是最快的方法。
I would suggest you don't care about this, until you get performance issues 我建议您不要担心这一点,直到遇到性能问题
If the performance issue is the your case: 如果您遇到性能问题:
NOTES 笔记
== UPDATE == ==更新==
Test results: 检测结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.