首頁 >web前端 >js教程 >通用的深度比較演算法如何有效地突出具有嵌套屬性、陣列和其他結構的複雜物件之間的差異?

通用的深度比較演算法如何有效地突出具有嵌套屬性、陣列和其他結構的複雜物件之間的差異?

Susan Sarandon
Susan Sarandon原創
2024-11-23 09:19:28771瀏覽

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