如何从两个具有高性能的数组中提取子数组?

时间:2017-01-24 12:50:43

标签: javascript arrays json performance

我有两个JSON对象数组:

  • 一个包含大约60.000个元素,代表我的参考数据集。内部的每个JSON都拥有一个键和一些其他属性。请注意,密钥可能不是数组中的uniq。
  • 另一个包含各种数量的元素(至少数千个)。内部的每个JSON都拥有一个键(也在第一个数组中定义)和其他一些属性。

e.g。 :

let refarray = [{key : 1, attr1 : 'aze', ...}, {key : 1, attr1 : 'zer', ...},{key : 2, attr1 : 'ert'},...]
let otherarray = [{key : 1, attr2 : 'wxc', ...}, {key : 3, attr2 : 'xcv'},...]

我只需要从refarray中提取其关键字存在于其他内容中的所有元素。

目前我使用loadash如下:

let newarray = _.filter(refarray , function(d) { return _.findIndex(otherarray , function(s) { return s.key=== d.key;}) >= 0});

但需要3到15秒,这太长了。欢迎任何最快的解决方案。感谢。

3 个答案:

答案 0 :(得分:1)

您可以尝试缓存otherarray的密钥,然后过滤refarray。我尝试了一个小样本(虽然我尝试了node而不是浏览器)并且它花了100多分钟的时间:

let refarray = []
let otherarray = []

for(let i of Array(60 * 1000).keys())
  refarray.push({ key: 1 + (i % 1200) })

for(let i of Array(1000).keys())
  otherarray.push({ key: i + 1 })

console.time('cache')
let cache = _.uniq(_.map(otherarray, n => n.key))
const inCache = n => cache.indexOf(n.key) !== -1

let newArray = _.filter(refarray, inCache)

console.timeEnd('cache')
console.log(refarray.length, otherarray.length, newArray.length);

答案 1 :(得分:1)

根据重复键的数量,EmilS.Jørgensen的解决方案可能不够理想。我会继续迭代第一个数组的不同值:

d2 = Date.now();
var distinct = [];
refarray.forEach(function(item) {
    if (distinct.indexOf(item.key) < 0) {
        distinct.push(item.key);
    }
});
console.log('Results:',otherarray.filter(function(item) {
    return distinct.indexOf(item.key) > -1;
}));
console.log('Milliseconds to filter:', Date.now() - d2);

答案 2 :(得分:0)

带有Array.prototype.filter

Array.prototype.some应该是最快的方法。

//Default ref
var refarray = [{
  key: 1,
  attr1: 'aze'
}, {
  key: 2,
  attr1: 'zer'
}];
//Default other
var otherarray = [{
  key: 1,
  attr2: 'wxc'
}, {
  key: 3,
  attr2: 'xcv'
}];
//Padding ref
while (refarray.length < 10 * 1000) {
  refarray.push({
    key: 5,
    attr1: 'aze'
  })
}
//Padding other
while (otherarray.length < 60 * 1000) {
  otherarray.push({
    key: 6,
    attr2: 'aze'
  })
}
console.log('Size of refarray:', refarray.length);
console.log('Size of otherarray:', otherarray.length);
var d = Date.now();
console.log('Results:',refarray.filter(function(a) {
  return otherarray.some(function(b) {
    return b.key == a.key
  })
}));
console.log('Milliseconds to filter:', Date.now() - d);