一.需求明确
实现此功能需要考虑的问题有,数组里面每一项的类型(数组、对象等),有可能是单独也有可能是嵌套式,所以需要用到递归来进行操作。
二.实现思路
我们需要定义两个函数:areObjectsEqual
和 arraysEqual
。它们用于比较两个数组中的对象是否相等:
areObjectsEqual
函数:这个函数用于比较两个对象是否相等。
if (obj1 === obj2) return true;
- 如果两个对象的引用相同,直接返回
true
。
if (obj1 == null || obj2 == null) return false;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
- 如果任何一个对象为
null
或者它们的类型不是object
,返回false
。
const entries1 = Object.entries(obj1);
const entries2 = Object.entries(obj2);
- 使用
Object.entries
方法将对象的键值对提取成一个数组,比较键值对的数量:
if (entries1.length !== entries2.length) return false;
- 如果两个对象的键值对数量不同,返回
false
,创建映射并比较:
const map = new Map(entries1);
for (let [key, value] of entries2) {
if (!map.has(key) || !deepEqual(map.get(key), value)) {
return false;
}
}
将第一个对象的键值对存储在 Map
中,然后遍历第二个对象的键值对。如果 Map
中不包含第二个对象的某个键,或者对应的值不同,返回 false
。deepEqual
函数应递归比较值,如果值是对象则调用 areObjectsEqual
。
arraysEqual
函数:这个函数用于比较两个数组中的对象是否相等。
- 比较数组长度:
if (arr1.length !== arr2.length) return false;
- 如果两个数组的长度不同,返回
false
,逐个对象比较:
for (let i = 0; i < arr1.length; i++) {
if (!areObjectsEqual(arr1[i], arr2[i])) return false;
}
- 遍历数组中的每个对象,调用
areObjectsEqual
函数比较对应位置的对象。如果任何一个对象不相等,返回false
。
const array1 = [{a: 1, b: 2}, {c: 3}];
const array2 = [{a: 1, b: 2}, {c: 3}];
const array3 = [{a: 1, b: 2}, {c: 4}];
console.log(arraysEqual(array1, array2)); // true
console.log(arraysEqual(array1, array3)); // false
// array1 和 array2 是相等的,因为它们包含的对象在每个位置上都相等。
// array1 和 array3 不相等,因为第二个对象 {c: 3} 与 {c: 4} 不相等。
注意
代码中 deepEqual
函数,递归调用 areObjectsEqual
函数来比较对象的嵌套属性,这种比较方法对性能要求较高,因为它需要遍历每个对象的每个属性。
function deepEqual(val1, val2) {
if (val1 === val2) return true;
if (val1 == null || val2 == null || typeof val1 !== 'object' || typeof val2 !== 'object') {
return false;
}
return areObjectsEqual(val1, val2);
}
三.示例代码
function deepEqual(val1, val2) {
if (val1 === val2) return true;
if (val1 == null || val2 == null || typeof val1 !== 'object' || typeof val2 !== 'object') {
return false;
}
return areObjectsEqual(val1, val2);
}
function areObjectsEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (obj1 == null || obj2 == null) return false;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
const entries1 = Object.entries(obj1);
const entries2 = Object.entries(obj2);
if (entries1.length !== entries2.length) return false;
const map = new Map(entries1);
for (let [key, value] of entries2) {
if (!map.has(key) || !deepEqual(map.get(key), value)) {
return false;
}
}
return true;
}
function arraysEqual(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
for (let i = 0; i < arr1.length; i++) {
if (!areObjectsEqual(arr1[i], arr2[i])) return false;
}
return true;
}
// 示例用法
const array1 = [{a: 1, b: 2}, {c: 3}];
const array2 = [{a: 1, b: 2}, {c: 3}];
const array3 = [{a: 1, b: 2}, {c: 4}];
console.log(arraysEqual(array1, array2)); // true
console.log(arraysEqual(array1, array3)); // false