问题
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