如何在array2中找到不在array1中的元素?

时间:2012-04-06 20:16:29

标签: javascript arrays diff

我有两个数组:

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长度的数组)

2 个答案:

答案 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}]

工作演示:http://jsfiddle.net/jfriend00/uDEtg/

答案 1 :(得分:0)

同样的问题已经发布了几次,看看这里:

JavaScript array difference

大多数解决方案都是通过'原生'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的对象。

如果两个数组的长度相等,那也没关系,因为我们会将所有项目与所有其他项目进行比较。