ホームページ > ウェブフロントエンド > jsチュートリアル > JavaScript でオブジェクトと配列の汎用 Deep Diff を実装するにはどうすればよいですか?

JavaScript でオブジェクトと配列の汎用 Deep Diff を実装するにはどうすればよいですか?

Barbara Streisand
リリース: 2024-11-15 12:58:02
オリジナル
491 人が閲覧しました

How to Implement a Generic Deep Diff for Objects and Arrays in JavaScript?

2 つのオブジェクト間の一般的な深差分

2 つのオブジェクトの深差分分析には、追加、更新、削除など、オブジェクト間の変更の識別が含まれます。これは、特にネストされたオブジェクトや配列の場合、複雑になる可能性があります。

汎用 Deep Diff の既存のライブラリまたはコード

1 つのアプローチは、変更を示すオブジェクト:

{add:{...},upd:{...},del:{...}}
ログイン後にコピー

ただし、オブジェクト構造内の更新をキャプチャするには、より詳細な表現が望ましいです。

更新されたオブジェクト構造を使用した拡張表現

改善された表現では、更新されたオブジェクト (newObj) と同じオブジェクト構造を使用しますが、プロパティ値をオブジェクトに変換します。

{type: '<update|create|delete>', data: <propertyValue>}
ログイン後にコピー

たとえば、newObj.prop1 = '新しい値' および oldObj の場合。 prop1 = 'old value' の場合、結果は次のようになります。

returnObj.prop1 = {type: 'update', data: 'new value'}
ログイン後にコピー

配列の処理

等価性の判断は簡単ではないため、配列ではさらに複雑さが生じます。たとえば、配列:

[1,[{c: 1},2,3],{a:'hey'}]
ログイン後にコピー

[{a:'hey'},1,[3,{c: 1},2]]
ログイン後にコピー

は等しいと見なされます。深い値の等価性を確認するのは複雑な場合があり、配列の変更を効果的に表現することも困難です。

サンプル実装

これは、一般的な深い比較を実行できるクラスの実装です。 :

var deepDiffMapper = function () {
  return {
    map: function(obj1, obj2) {
      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
        };
      }

      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);
      }
      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) {
      if (value1 === value2) {
        return this.VALUE_UNCHANGED;
      }
      if (this.isDate(value1) &amp;&amp; this.isDate(value2) &amp;&amp; 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;
    },
    ...
  }
}();
ログイン後にコピー

使用例:

var result = deepDiffMapper.map({
  a: 'i am unchanged',
  b: 'i am deleted',
  ...
}, {
  a: 'i am unchanged',
  c: 'i am created',
  ...
});
console.log(result);
ログイン後にコピー

以上がJavaScript でオブジェクトと配列の汎用 Deep Diff を実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート