Compare arrays of objects independent of the order

為{幸葍}努か 提交于 2020-01-14 10:23:17

问题


I have 2 arrays of objects and I have to compare them, but the order of the objects DOES NOT matter. I can't sort them because I won't have their keys' names because the functions must be generic. The only information that I'll have about the array is that both array's objects have the same amount of keys and those keys have the same name. So the array1 must contain the same objects as the array2.

var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}];
var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];

In the example, array1 must be equal array2. I tryed to use the chai .eql() method but it didn't work.


回答1:


You can array#join each value of the object on an separator and then generate a new array of string and then compare each values using array#every and array#includes

var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}];
    array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];
    values = (o) => Object.keys(o).sort().map(k => o[k]).join('|'),
    mapped1 = array1.map(o => values(o)),
    mapped2 = array2.map(o => values(o));

var res = mapped1.every(v => mapped2.includes(v));

console.log(res);



回答2:


For a solution that requires the arrays to have an equal number of elements, does not require keys to not contain a certain delimiter, requires both keys and (string) values to be the same, and runs in O(nlogn) instead of O(n²):

function equalArrays(a, b) {
    if (a.length !== b.length) return false;
    const ser = o => JSON.stringify(Object.keys(o).sort().map( k => [k, o[k]] ));
    a = new Set(a.map(ser));
    return b.every( o => a.has(ser(o)) );
}

// Example
var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}];
var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];
console.log(equalArrays(array1, array2)); // true
// Example with different key name
var array1 = [{"key0":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}];
var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];
console.log(equalArrays(array1, array2)); // false



回答3:


You can do something like following:

For each object in each array you can calc its representation:

arr1.forEach( (obj) => {
    obj.representation = '';
    for (let key of Object.keys(obj)) {
      obj.representation += obj[key];
    }
}

Same for arr2

now you can sort both arrays by representation for example and then compare.

To sort do the following:

arr1.sort( (a,b) => { return a.representation > b.representation } );
arr2.sort( (a,b) => { return a.representation > b.representation } );

After sorting you can compare both arrays

let equal = arr1.every( (el, i) => arr2[i]===el );


来源:https://stackoverflow.com/questions/47041348/compare-arrays-of-objects-independent-of-the-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!