深比较的方法有哪些?

简介: 【10月更文挑战第29天】

递归比较

  • 原理:通过递归遍历对象或数组的所有属性和元素,对每个属性或元素进行逐一比较,直到比较完所有层级的内容。
  • 示例
function deepEqual(obj1, obj2) {
   
  if (obj1 === obj2) {
   
    return true;
  }

  if (typeof obj1!== 'object' || obj1 === null || typeof obj2!== 'object' || obj2 === null) {
   
    return false;
  }

  if (Array.isArray(obj1) && Array.isArray(obj2)) {
   
    if (obj1.length!== obj2.length) {
   
      return false;
    }
    for (let i = 0; i < obj1.length; i++) {
   
      if (!deepEqual(obj1[i], obj2[i])) {
   
        return false;
      }
    }
    return true;
  } else {
   
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length!== keys2.length) {
   
      return false;
    }

    for (let key of keys1) {
   
      if (!obj2.hasOwnProperty(key) ||!deepEqual(obj1[key], obj2[key])) {
   
        return false;
      }
    }

    return true;
  }
}

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(deepEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(deepEqual(obj3, obj4)); // true

JSON序列化比较

  • 原理:先将对象或数组转换为JSON字符串,然后比较这两个JSON字符串是否相等。如果相等,则说明两个对象或数组的内容在结构和值上是相同的。
  • 示例
function jsonDeepEqual(obj1, obj2) {
   
  return JSON.stringify(obj1) === JSON.stringify(obj2);
}

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(jsonDeepEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(jsonDeepEqual(obj3, obj4)); // true

不过需要注意的是,JSON序列化比较要求对象的属性值必须是能够被JSON序列化的数据类型,如函数、正则表达式等特殊类型在序列化时会丢失信息,导致比较结果不准确。

lodash库的_.isEqual方法

  • 原理:lodash是一个常用的JavaScript工具库,其中的 _.isEqual 方法实现了深度比较的功能。它能够递归地比较对象、数组以及各种数据类型的差异,并且能够处理循环引用等复杂情况。
  • 示例
    首先需要安装lodash库,然后可以这样使用:
const _ = require('lodash');

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(_.isEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(_.isEqual(obj3, obj4)); // true

自定义深度比较函数

  • 原理:根据具体的业务需求和对象结构,编写自定义的深度比较函数,在函数中明确指定比较的规则和逻辑,对对象的各个属性和嵌套层次进行细致的比较。
  • 示例
function customDeepEqual(obj1, obj2) {
   
  // 比较对象的类型是否相同
  if (Object.prototype.toString.call(obj1)!== Object.prototype.toString.call(obj2)) {
   
    return false;
  }

  if (typeof obj1 === 'object' && obj1!== null) {
   
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length!== keys2.length) {
   
      return false;
    }

    for (let key of keys1) {
   
      if (!obj2.hasOwnProperty(key)) {
   
        return false;
      }

      if (typeof obj1[key] === 'object' && obj1[key]!== null) {
   
        if (!customDeepEqual(obj1[key], obj2[key])) {
   
          return false;
        }
      } else {
   
        if (obj1[key]!== obj2[key]) {
   
          return false;
        }
      }
    }
  }

  return true;
}

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(customDeepEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(customDeepEqual(obj3, obj4)); // true

这些深比较的方法各有优缺点,在实际应用中,可以根据具体的场景和需求选择合适的方法来进行深度比较。递归比较方法较为灵活但需要自己处理各种边界情况;JSON序列化比较简单直接但对数据类型有一定限制;使用lodash库的 _.isEqual 方法方便快捷且功能强大,但需要引入额外的库;自定义深度比较函数则可以根据特定的业务逻辑进行精确的比较。

相关文章
|
3天前
|
JSON JavaScript 前端开发
除了递归比较,还有哪些方法可以进行深比较?
【10月更文挑战第29天】在实际应用中,可以根据具体的项目需求、数据结构特点以及性能要求等因素,选择合适的深比较方法。如果对性能要求不高且数据结构较简单,JSON序列化比较可能是一个简单有效的选择;如果需要处理复杂的数据结构和各种特殊情况,使用lodash或underscore.js等成熟的库可能更为可靠和便捷;而对于一些具有特殊比较逻辑的场景,则可以考虑编写自定义的比较函数。
|
4月前
|
存储 Java 程序员
【c++】继承深度解剖
【c++】继承深度解剖
36 1
|
4月前
|
存储 安全 程序员
【C++11】C++11深度解剖(上)
【C++11】C++11深度解剖(上)
33 0
|
4月前
|
存储 算法 编译器
【C++11】C++11深度解剖(下)
【C++11】C++11深度解剖(下)
34 0
|
6月前
【从浅入深,全面掌握数组的操作与优化技巧】
【从浅入深,全面掌握数组的操作与优化技巧】
|
6月前
|
存储 C++ 容器
由浅到深-模拟实现list
由浅到深-模拟实现list
|
6月前
|
搜索推荐 Java Shell
8大Java排序方法(由简入繁),有代码详解和原理指导
8大Java排序方法(由简入繁),有代码详解和原理指导
57 0
|
编译器 C#
【C#本质论 七】类-从设计的角度去认知(继承)(下)
【C#本质论 七】类-从设计的角度去认知(继承)(下)
67 0
|
存储 开发框架 .NET
【C#本质论 七】类-从设计的角度去认知(继承)(上)
【C#本质论 七】类-从设计的角度去认知(继承)(上)
90 0
|
存储 Java 程序员
【C#本质论 六】类-从设计的角度去认知(封装)(上)
【C#本质论 六】类-从设计的角度去认知(封装)(上)
108 0