比较独立于顺序的对象数组
Compare arrays of objects independent of the order
我有 2 个对象数组,我必须比较它们,但是对象的顺序 不 重要。我无法对它们进行排序,因为我没有它们的键名,因为这些函数必须是通用的。关于该数组,我将获得的唯一信息是两个数组的对象具有相同数量的键,并且这些键具有相同的名称。所以 array1 必须包含与 array2 相同的对象。
var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}];
var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];
在示例中,array1 必须等于array2。
我尝试使用 chai .eql()
方法,但它没有用。
您可以执行以下操作:
对于每个数组中的每个对象,您可以计算其表示形式:
arr1.forEach( (obj) => {
obj.representation = '';
for (let key of Object.keys(obj)) {
obj.representation += obj[key];
}
}
arr2
也一样
现在您可以按表示形式对两个数组进行排序,然后进行比较。
要排序,请执行以下操作:
arr1.sort( (a,b) => { return a.representation > b.representation } );
arr2.sort( (a,b) => { return a.representation > b.representation } );
排序后你可以比较两个数组
let equal = arr1.every( (el, i) => arr2[i]===el );
您可以 array#join
分隔符上对象的每个值,然后生成一个新的字符串数组,然后使用 array#every
和 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);
以下解决方案:
- 将验证数组的元素数量是否相等
- 不对key进行限制(至于不包含一定的分隔符)
- 要求键和(字符串)值相同
- 的时间复杂度为 O(nlogn)(而不是 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
我有 2 个对象数组,我必须比较它们,但是对象的顺序 不 重要。我无法对它们进行排序,因为我没有它们的键名,因为这些函数必须是通用的。关于该数组,我将获得的唯一信息是两个数组的对象具有相同数量的键,并且这些键具有相同的名称。所以 array1 必须包含与 array2 相同的对象。
var array1 = [{"key1":"Banana", "key2":"Yammy"}, {"key1":"Broccoli", "key2":"Ew"}];
var array2 = [{"key1":"Broccoli", "key2":"Ew"}, {"key1":"Banana", "key2":"Yammy"}];
在示例中,array1 必须等于array2。
我尝试使用 chai .eql()
方法,但它没有用。
您可以执行以下操作:
对于每个数组中的每个对象,您可以计算其表示形式:
arr1.forEach( (obj) => {
obj.representation = '';
for (let key of Object.keys(obj)) {
obj.representation += obj[key];
}
}
arr2
现在您可以按表示形式对两个数组进行排序,然后进行比较。
要排序,请执行以下操作:
arr1.sort( (a,b) => { return a.representation > b.representation } );
arr2.sort( (a,b) => { return a.representation > b.representation } );
排序后你可以比较两个数组
let equal = arr1.every( (el, i) => arr2[i]===el );
您可以 array#join
分隔符上对象的每个值,然后生成一个新的字符串数组,然后使用 array#every
和 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);
以下解决方案:
- 将验证数组的元素数量是否相等
- 不对key进行限制(至于不包含一定的分隔符)
- 要求键和(字符串)值相同
- 的时间复杂度为 O(nlogn)(而不是 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