首页 > 其他分享 >[代码实现]S 中如何实现大对象深度对比

[代码实现]S 中如何实现大对象深度对比

时间:2025-01-01 19:10:15浏览次数:1  
标签:obj1 obj2 const 实现 代码 Object 对象 深度 return

以下是在 JavaScript 中实现大对象深度对比的几种方法:

方法一:递归比较

function deepEqual(obj1, obj2) {
  // 首先比较两个对象是否为同一引用
  if (obj1 === obj2) {
    return true;
  }

  // 检查是否都是对象且不为 null
  if (typeof obj1!== 'object' || obj1 === null || typeof obj2!== 'object' || obj2 === null) {
    return false;
  }

  // 获取对象的键列表
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  // 检查键的数量是否相同
  if (keys1.length!== keys2.length) {
    return false;
  }

  // 递归比较每个键对应的值
  for (const key of keys1) {
    if (!keys2.includes(key) ||!deepEqual(obj1[key], obj2[key])) {
      return false;
    }
  }

  return true;
}

// 示例使用
const objA = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
const objB = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
console.log(deepEqual(objA, objB)); // true

解释

  • 首先,检查两个对象是否为同一引用,如果是,则认为它们相等。
  • 接着,检查对象是否为非对象或 null,如果是,则认为它们不相等。
  • 然后,比较两个对象的键的数量,如果不同,它们不相等。
  • 最后,递归比较每个键对应的值,如果有一个键的值不相等,它们不相等。

方法二:使用 JSON 序列化

function deepEqualWithJSON(obj1, obj2) {
  const str1 = JSON.stringify(obj1);
  const str2 = JSON.stringify(obj2);
  return str1 === str2;
}

// 示例使用
const objA = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
const objB = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
console.log(deepEqualWithJSON(objA, objB)); // true

解释

  • 将两个对象序列化为 JSON 字符串。
  • 比较两个 JSON 字符串是否相等。
  • 这种方法的缺点是无法处理函数、undefinedSymbol 等特殊值,因为 JSON.stringify 会将它们转换为 null 或忽略。

方法三:使用 Lodash 库

首先,你需要安装 Lodash 库:

npm install lodash

然后使用 Lodash 的 isEqual 方法:

const _ = require('lodash');

const objA = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
const objB = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
console.log(_.isEqual(objA, objB)); // true

解释

  • Lodash 的 isEqual 方法是一个功能强大的工具,可以深度比较两个对象,包括对象的属性和嵌套对象、数组、函数等。
  • 它可以处理 undefinedSymbol、函数等特殊值,并且可以处理对象的循环引用。

方法四:使用递归和 Object.entries

function deepEqualWithEntries(obj1, obj2) {
  // 首先比较两个对象是否为同一引用
  if (obj1 === obj2) {
    return true;
  }

  // 检查是否都是对象且不为 null
  if (typeof obj1!== 'object' || obj1 === null || typeof obj2!== 'object' || obj2 === null) {
    return false;
  }

  // 获取对象的键值对列表
  const entries1 = Object.entries(obj1);
  const entries2 = Object.entries(obj2);

  // 检查键值对的数量是否相同
  if (entries1.length!== entries2.length) {
    return false;
  }

  // 递归比较每个键值对
  for (const [key, value] of entries1) {
    if (!Object.hasOwnProperty.call(obj2, key) ||!deepEqualWithEntries(value, obj2[key])) {
      return false;
    }
  }

  return true;
}

// 示例使用
const objA = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
const objB = {
  a: 1,
  b: {
    c: 2,
    d: [3, 4]
  }
};
console.log(deepEqualWithEntries(objA, objB)); // true

解释

  • 类似于第一种方法,但使用 Object.entries 来获取对象的键值对列表,方便比较。
  • 对于每个键值对,递归比较其值是否相等。

总结

  • 方法一:适合大多数情况,代码简单,易于理解,但对于循环引用会导致栈溢出。
  • 方法二:简单快速,但无法处理 undefinedSymbol、函数等特殊值。
  • 方法三:功能强大,适用于各种复杂情况,但需要引入外部库。
  • 方法四:是方法一的变种,使用 Object.entries 代替 Object.keys,提供了一种不同的实现方式。

根据你的具体需求,可以选择最适合的方法进行大对象的深度比较。如果你需要处理复杂的对象,包括特殊值和循环引用,推荐使用 Lodash 的 isEqual 方法。

标签:obj1,obj2,const,实现,代码,Object,对象,深度,return
From: https://www.cnblogs.com/zsnhweb/p/18646199

相关文章

  • 虚拟滚动加加载的原理和实现思路
    以下是关于虚拟滚动加加载的原理和实现思路:一、虚拟滚动原理1.基本概念可视区域:用户在屏幕上看到的部分,是实际渲染内容的窗口。只有处于可视区域内的元素才会被渲染到DOM中,而其他部分不会被渲染,从而减少DOM元素的数量,提高性能。2.实现思路数据存储与显示:存储......
  • CKEDITOR实现WORD图片粘贴上传
    要求:开源,免费,技术支持编辑器:ckeditor前端:vue2,vue3.vue-cli后端:asp,java,jsp,springboot,php,asp.net,.netcore功能:复制粘贴word内容图片平台:Windows,macOS,Linux,RedHat,Ubuntu,CentOS,中标麒麟,银河麒麟,统信UOS,信创国产化操作系统CPU:x86(Intel,AMD,兆芯,海光),ar......
  • Java面试要点111 - Java BlockingQueue实现原理
    文章目录引言一、BlockingQueue基本概念二、主要实现类解析2.1ArrayBlockingQueue实现原理2.2LinkedBlockingQueue实现原理三、高级特性应用3.1优先级队列实现3.2延迟队列实现四、实际应用场景4.1生产者-消费者模式总结引言BlockingQueue是Java并发包中的......
  • 用 nodejs 实现一个命令行工具,统计输入目录下面指定代码的行数
    以下是一个使用Node.js实现的命令行工具,用于统计输入目录下指定代码文件的行数。实现思路接收命令行参数,获取输入目录和文件扩展名(例如,.js、.html、.css等)。递归遍历输入目录,查找所有符合指定扩展名的文件。对于每个找到的文件,读取文件内容并统计行数。输出统计结果。......
  • 实现站点一键换肤功能实现方式有哪些
    以下是一些常见的站点一键换肤功能的实现方式:使用CSS变量原理:通过CSS变量(CustomProperties)来管理站点的主题颜色、背景、字体等样式属性,用户切换主题时,只需要改变这些CSS变量的值,页面的样式会自动更新。实现方式:在全局样式中定义CSS变量,如--primary-color:#3498db;--backgr......
  • 如何实现网页加载进度条
    基于HTML5和JavaScript的简单进度条实现原理:利用window.onload事件和document.readyState属性来跟踪页面加载进度。document.readyState有不同的状态值,如loading(正在加载)、interactive(文档已被解析,“交互时间”开始)和complete(文档和所有子资源已完成加载)。实现步骤:首先,在HT......
  • 深度剖析 Linux 权限:原理、构成与实操
    深度剖析Linux权限:原理、构成与实操在Linux操作系统的复杂生态中,权限管理犹如精密的齿轮组,有条不紊地驱动着系统资源的安全分配与有序访问。它是保障多用户环境下数据隐私、系统稳定的关键防线,从文件到目录,每一次读写执行操作的背后,都有着权限规则的默默守护。下面就来......
  • Spring Data REST 远程代码执行漏洞(CVE-2017-8046)分析与复现2
    前言2009年9月Spring3.0RC1发布后,Spring就引入了SpEL(SpringExpressionLanguage)。对于开发者而言,引入新的工具显然是令人兴奋的,但是对于运维人员,也许是噩耗的开始。类比Struts2框架,会发现绝大部分的安全漏洞都和ognl脱不了干系。尤其是远程命令执行漏洞,占据了多少甲方乙方......
  • Spring Data REST 远程代码执行漏洞(CVE-2017-8046)分析与复现11
    前言2009年9月Spring3.0RC1发布后,Spring就引入了SpEL(SpringExpressionLanguage)。对于开发者而言,引入新的工具显然是令人兴奋的,但是对于运维人员,也许是噩耗的开始。类比Struts2框架,会发现绝大部分的安全漏洞都和ognl脱不了干系。尤其是远程命令执行漏洞,占据了多少甲方乙方......
  • Spring Data REST 远程代码执行漏洞(CVE-2017-8046)分析与复现10
    前言2009年9月Spring3.0RC1发布后,Spring就引入了SpEL(SpringExpressionLanguage)。对于开发者而言,引入新的工具显然是令人兴奋的,但是对于运维人员,也许是噩耗的开始。类比Struts2框架,会发现绝大部分的安全漏洞都和ognl脱不了干系。尤其是远程命令执行漏洞,占据了多少甲方乙方......