0

我有两个数组:

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

4

2 回答 2

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/

于 2012-04-06T20:24:06.713 回答
0

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

JavaScript 数组的区别

然而,大多数解决方案都是通过“本机”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);

我首先确定了最长的数组,我这样做是因为我想将尽可能多的对象与较短的列表进行比较。否则我们会“忘记”一些。

然后我只需在 underscore.js 库中使用 filter 和 find 来返回不在较短数组中但在较长数组中的对象。

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

于 2012-04-06T20:21:11.087 回答