js比较两个数组是否相等

发布于:2024-05-21 ⋅ 阅读:(160) ⋅ 点赞:(0)

一.需求明确

实现此功能需要考虑的问题有,数组里面每一项的类型(数组、对象等),有可能是单独也有可能是嵌套式,所以需要用到递归来进行操作。

二.实现思路

我们需要定义两个函数:areObjectsEqualarraysEqual。它们用于比较两个数组中的对象是否相等:

areObjectsEqual 函数:这个函数用于比较两个对象是否相等。

if (obj1 === obj2) return true;
  1. 如果两个对象的引用相同,直接返回 true
if (obj1 == null || obj2 == null) return false;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
  1. 如果任何一个对象为 null 或者它们的类型不是 object,返回 false
const entries1 = Object.entries(obj1);
const entries2 = Object.entries(obj2);
  1. 使用 Object.entries 方法将对象的键值对提取成一个数组,比较键值对的数量:
if (entries1.length !== entries2.length) return false;
  1. 如果两个对象的键值对数量不同,返回 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 中不包含第二个对象的某个键,或者对应的值不同,返回 falsedeepEqual 函数应递归比较值,如果值是对象则调用 areObjectsEqual


arraysEqual 函数:这个函数用于比较两个数组中的对象是否相等。

  1. 比较数组长度:
if (arr1.length !== arr2.length) return false;
  1. 如果两个数组的长度不同,返回 false,逐个对象比较:
for (let i = 0; i < arr1.length; i++) {
  if (!areObjectsEqual(arr1[i], arr2[i])) return false;
}
  1. 遍历数组中的每个对象,调用 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

网站公告

今日签到

点亮在社区的每一天
去签到