我有两个数组:
var a1 = [ { ID: 2, N:0 }, { ID: 1, N:0 } ];
var a2 = [ { ID: 1, N:0 }, { ID: 2, N:0 }, { ID: 3, N:0 } ];
我需要获取a2
上但a1
中没有的所有元素。此处的元素仅由属性ID
与另一个元素区分开,其他属性应该被忽略。而且我不能保证数组上元素的顺序。意味着此示例的结果应为:
var result = [ { ID: 3, N:0 } ]; // result for the example above
我怎样才能以有效的方式做到这一点? (我将比较500到5,000长度的数组)
答案 0 :(得分:3)
要有效地执行此操作,您需要构建已包含在a1中的项目的索引,以便您可以循环浏览a2并将每个项目与索引进行比较,以查看它是否已被查看。可以使用javascript对象作为索引。循环浏览a1并将其所有ID放入索引中。然后循环浏览a2并收集ID未出现在索引中的任何项目。
function findUniques(testItems, baseItems) {
var index = {}, i;
var result = [];
// put baseItems id values into the index
for (i = 0; i < baseItems.length; i++) {
index[baseItems[i].ID] = true;
}
// now go through the testItems and collect the items in it
// that are not in the index
for (i = 0; i < testItems.length; i++) {
if (!(testItems[i].ID in index)) {
result.push(testItems[i]);
}
}
return(result);
}
var a1 = [ { ID: 2, N:0 }, { ID: 1, N:0 } ];
var a2 = [ { ID: 1, N:0 }, { ID: 2, N:0 }, { ID: 3, N:0 } ];
var result = findUniques(a2, a1);
// [{"ID":3,"N":0}]
答案 1 :(得分:0)
同样的问题已经发布了几次,看看这里:
大多数解决方案都是通过'原生'javascript提供的。我有时更喜欢使用underscore.js,因为我使用backbone.js构建了很多东西,而下划线是Backbone的依赖。所以我可以使用它的真棒实用程序。您可以考虑将它们加载到:
http://documentcloud.github.com/underscore/
var a1 = [ { ID: 2, N:0 }, { ID: 1, N:0 } ];
var a2 = [ { ID: 1, N:0 }, { ID: 2, N:0 }, { ID: 3, N:0 } ];
var from, to;
if(a1 > a2){
from = a1
to = a2
} else {
from = a2
to = a1
}
var a3 = _.filter(from, function(obj){
var compare = _.find(to, function(obj2){ return obj.ID === obj2.ID });
return compare === undefined
});
console.log(a3);
我首先确定了最长的数组,我这样做是因为我想将尽可能多的对象与较短的列表进行比较。否则我们会'忘记'一些。
然后我只是使用filter并在underscore.js库中找到返回不在较短数组中但在较长数组中的ARE的对象。
如果两个数组的长度相等,那也没关系,因为我们会将所有项目与所有其他项目进行比较。