简体   繁体   English

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

[英]Javascript array with associative array difference

Is there a way to return the difference between two arrays in JavaScript? 有没有办法在JavaScript中返回两个数组之间的差异? I can not use indexOf in this case. 在这种情况下我不能使用indexOf。

For example: 例如:

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

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

Please advise. 请指教。

As I mentioned in my comment, objects are only equal if they refer to the same instance. 正如我在评论中提到的,如果对象引用相同的实例,则它们只是相等的。 Therefore, any built-in system will not do, least of all == and === . 因此,任何内置系统都不会,尤其是===== So, first you must define your own comparison function. 所以,首先你必须定义自己的比较函数。

Let's say that two objects are equal if they contain the same keys with the same values. 假设两个对象包含具有相同值的相同键,则它们是相等的。

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);
}

Okay, now that that's out of the way, we can compare our functions. 好的,现在已经不在了,我们可以比较一下我们的功能。

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;
}

And there you go! 你去吧!

One object can never be the same as another object even if they have the same content. 一个对象永远不会与另一个对象相同,即使它们具有相同的内容。 They would still be different instances of Objects. 它们仍然是对象的不同实例。

That means you have to compare keys and values to check that they match, or in this case, don't match. 这意味着您必须比较键和值以检查它们是否匹配,或者在这种情况下,不匹配。

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 小提琴

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' } ]

Easy and simple way to achieve your goal 轻松简单的方法来实现您的目标

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 的jsfiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM