Javascript array with associative array difference

Is there a way to return the difference between two arrays in JavaScript? I can not use indexOf in this case.

For instance:

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

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

Please inform.

+4
source share
4 answers

A simple and easy 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 elements back in object do following iteration
for ( var i in newArray ) { // loop recreate results array elements into object again
    newArray[i] = JSON.parse(newArray[i]);
}

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

Jsfiddle

0
source

As I mentioned in my comment, objects are equal if they refer to the same instance. Therefore, any embedded system will not do the least ==and ===. So, first you have to 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);
}

Well, now that this is not possible, 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 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;
}

!

+2

One object can never be the same as another object, even if it has the same content. They will still be different instances of objects.

This means that you need to compare keys and values ​​to make sure they match or don't match in this case.

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

Source: https://habr.com/ru/post/1530210/


All Articles