具有关联数组差异的Javascript数组

时间:2014-03-05 09:49:42

标签: javascript

有没有办法在JavaScript中返回两个数组之间的差异? 在这种情况下我不能使用indexOf。

例如:

var a1 = [{"a":"A"},{"b":"B"}];
var a2 = [{"a":"A"},{"b":"B"},{"c":"C"}];

// need [{"c":"C"}]

请告知。

4 个答案:

答案 0 :(得分:2)

正如我在评论中提到的,如果对象引用同一个实例,则它们只是相等的。因此,任何内置系统都不会,尤其是=====。所以,首先你必须定义自己的比较函数。

假设两个对象包含具有相同值的相同键,则它们是相等的。

function areObjectsEqual(a,b) {
    function helper(a,b) {
        var k;
        for( k in a) {
            if( a.hasOwnProperty(k)) {
                if( !b.hasOwnProperty(k)) return false;
                if( typeof a[k] != typeof b[k]) return false;
                if( typeof a[k] == "object") {
                    if( !areObjectsEqual(a[k],b[k])) return false;
                    // the above line allows handling of nested objects
                }
                else {
                    if( a[k] != b[k]) return false;
                    // this comparison is technically strict
                    // because we already checked typeof earlier
                }
            }
        }
    }
    return helper(a,b) && helper(b,a);
}

好的,现在已经不在了,我们可以比较一下我们的功能。

function array_diff(a,b) {
    var result = [], l = a.length, i, m = b.length, j;
    outer:
    for( i=0; i<l; i++) {
        for( j=0; j<m; j++) {
            if( typeof a[i] != typeof b[j]) continue;
            if( typeof a[i] == "object") {
                if( !areObjectsEqual(a[i],b[j])) continue;
            }
            else {
                if( a[i] != b[j]) continue;
            }
            // if we got to here, it's a match!
            // ... so actually we want to skip over the result :p
            continue outer;
        }
        // okay, if we get HERE then there was no match,
        // because we skipped the "continue outer"
        result.push(a[i]);
    }
    return result;
}

你去了!

答案 1 :(得分:2)

一个对象永远不会与另一个对象相同,即使它们具有相同的内容。它们仍然是对象的不同实例。

这意味着您必须比较键和值以检查它们是否匹配,或者在这种情况下,不匹配。

var a1 = [{"a":"A"},{"b":"B"}];
var a2 = [{"a":"A"},{"b":"B"},{"c":"C"}];

var a3 = a2.filter(function(o) {
    return Object.keys(o).some(function(k) {
        return a1.every(function(o2) {
            return !(k in o2) || (o2[k] != o[k]);
        });
    });
});

FIDDLE

答案 2 :(得分:0)

var a1 = [{"a":"A"},{"b":"B"}];
var a2 = [{"a":"A"},{"b":"B"},{"c":"C"}];
var obj = {}, result = [];

function updateObjectCount(currentItem) {
    var keys, key;
    for (key in currentItem) {
        if (currentItem.hasOwnProperty(key)) {
            keys = key;
            break;
        }
    }
    obj[key] = obj[key] || {};
    obj[key][currentItem[key]] = (obj[key][currentItem[key]] || 0) + 1;
}

a1.forEach(updateObjectCount);
a2.forEach(updateObjectCount);

for (var key1 in obj) {
    if (obj.hasOwnProperty((key1))) {
        for (var key2 in obj[key1]) {
            if (obj.hasOwnProperty((key1))) {
                if (obj[key1][key2] === 1) {
                    var temp = {};
                    temp[key1] = key2;
                    result.push(temp)
                }
            }
        }
    }
}

console.log(result);
# [ { c: 'C' } ]

答案 3 :(得分:0)

实现目标的简单方法

var a1 = [{"a":"A"},{"b":"B"}];
var a2 = [{"a":"A"},{"c":"C"},{"b":"B"}];

var max = (a1.length > a2.length) ? a1 : a2;
var min = (a1.length > a2.length) ? a2 : a1;
var newArray = [];

for ( var i = 0; i < max.length; i++ ) { // saving elements into string
    max[i] = JSON.stringify(max[i]);
    if ( typeof min[i] !== undefined ) {
        min[i] = JSON.stringify(min[i]);
    }
}

for ( var i = 0; i < max.length; i++ ) { // checking values uniqueness
    if ( min.indexOf(max[i]) === -1 ) {
        newArray.push(max[i]);
    }
}

// if you need new Array's elements back in object do following iteration
for ( var i in newArray ) { // loop recreate results array's elements into object again
    newArray[i] = JSON.parse(newArray[i]);
}

console.log(newArray); // result : [Object { c="C"}]

JSFiddle