首页 >web前端 >js教程 >通用的深度比较算法如何有效地突出具有嵌套属性、数组和其他结构的复杂对象之间的差异?

通用的深度比较算法如何有效地突出具有嵌套属性、数组和其他结构的复杂对象之间的差异?

Susan Sarandon
Susan Sarandon原创
2024-11-23 09:19:28834浏览

How can a generic deep diff algorithm effectively highlight differences between complex objects with nested properties, arrays, and other structures?

两个对象之间的通用深度差异

在软件开发中,经常需要确定两个对象之间的差异。当处理原始数据类型时,这可能是一个简单的过程,但当处理包含嵌套属性、数组和其他复杂结构的深层对象时,这会变得更加复杂。

实现细节

我最近遇到这一挑战并发现通用的深度差异算法是最有效的方法。这涉及递归遍历两个对象,比较它们的值,并生成表示差异的结果对象。

为了实现这一点,我开发了以下解决方案:

const deepDiffMapper = {
  VALUE_CREATED: 'created',
  VALUE_UPDATED: 'updated',
  VALUE_DELETED: 'deleted',
  VALUE_UNCHANGED: 'unchanged',
  map: function(obj1, obj2) {
    // Handling functions and primitive values separately.
    if (this.isFunction(obj1) || this.isFunction(obj2)) {
      throw 'Invalid argument. Function given, object expected.';
    }
    if (this.isValue(obj1) || this.isValue(obj2)) {
      return {
        type: this.compareValues(obj1, obj2),
        data: obj1 === undefined ? obj2 : obj1
      };
    }

    // Building a diff object for nested properties.
    var diff = {};
    for (var key in obj1) {
      if (this.isFunction(obj1[key])) {
        continue;
      }
      var value2 = undefined;
      if (obj2[key] !== undefined) {
        value2 = obj2[key];
      }
      diff[key] = this.map(obj1[key], value2);
    }

    // Adding properties present in obj2 but not in obj1.
    for (var key in obj2) {
      if (this.isFunction(obj2[key]) || diff[key] !== undefined) {
        continue;
      }
      diff[key] = this.map(undefined, obj2[key]);
    }
    return diff;
  },
  compareValues: function (value1, value2) {
    // Comparison of primitive values, dates, and null.
    if (value1 === value2) {
      return this.VALUE_UNCHANGED;
    }
    if (this.isDate(value1) && this.isDate(value2) && value1.getTime() === value2.getTime()) {
      return this.VALUE_UNCHANGED;
    }
    if (value1 === undefined) {
      return this.VALUE_CREATED;
    }
    if (value2 === undefined) {
      return this.VALUE_DELETED;
    }
    return this.VALUE_UPDATED;
  },
  ...helper functions...
};

示例用法

为了说明此解决方案,请考虑以下两个对象:

const oldObj = {
  a: 'i am unchanged',
  b: 'i am deleted',
  e: {
    a: 1,
    b: false,
    c: null
  },
  f: [1, {
    a: 'same',
    b: [{
      a: 'same'
  }, {
    d: 'delete'
  }]
}],
g: new Date('2017.11.25')
};

const newObj = {
  a: 'i am unchanged',
  c: 'i am created',
  e: {
    a: '1',
    b: '',
    d: 'created'
  },
  f: [{
  a: 'same',
  b: [{
    a: 'same'
  }, {
    c: 'create'
  }]
  }, 1],
  g: new Date('2017.11.25')
};

运行深度差异对这些对象进行算法将产生以下结果:

{
  a: { type: 'unchanged' },
  b: { type: 'deleted' },
  c: { type: 'created', data: 'i am created' },
  e: {
    a: { type: 'updated', data: '1' },
    b: { type: 'updated', data: '' },
    c: { type: 'unchanged' },
    d: { type: 'created', data: 'created' }
  },
  f: {
    0: { type: 'unchanged' },
    1: {
      a: { type: 'unchanged' },
      b: {
        0: { type: 'unchanged' },
        1: { type: 'deleted' },
        2: { type: 'created', data: { c: 'create' } }
      }
    }
  }
}

这个结果准确地捕获了两个对象之间的差异,表明属性“b”被删除,创建了新属性“c”, “e”对象有几个更新和创建的属性,并且数组“f”经历了一些更改。

以上是通用的深度比较算法如何有效地突出具有嵌套属性、数组和其他结构的复杂对象之间的差异?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn