ホームページ >ウェブフロントエンド >jsチュートリアル >2 つのオブジェクトを比較 (diff) する方法

2 つのオブジェクトを比較 (diff) する方法

DDD
DDDオリジナル
2024-10-23 19:44:02907ブラウズ

How to Compare (diff) two Objects

JavaScript でのオブジェクトの比較

JavaScript でのオブジェクト比較は一見複雑です。数値や文字列などのプリミティブな値の比較は簡単ですが、オブジェクトの比較は予期しない結果につながる可能性があります。オブジェクト比較のさまざまなアプローチを検討し、オブジェクト間の変更を検出するための堅牢なソリューションを構築しましょう。

直接比較の落とし穴

開発者が初めて JavaScript でオブジェクトの比較に遭遇したとき、多くの場合、次のようなことを試みます。

const user1 = { name: "John", age: 30 };
const user2 = { name: "John", age: 30 };

console.log(user1 === user2); // false

驚くべきことに、両方のオブジェクトの内容が同じであるにもかかわらず、これは false を返します。これは、JavaScript がオブジェクトの値ではなくオブジェクト参照を比較するために発生します。どちらのオブジェクトもメモリ内の異なる場所を指します。

単純な比較アプローチ

1.JSON.stringify

オブジェクトを比較する簡単な方法は、JSON.stringify を使用することです:

const areEqual = (obj1, obj2) => 
  JSON.stringify(obj1) === JSON.stringify(obj2);

console.log(areEqual(user1, user2)); // true

これは単純な場合には機能しますが、次のような制限があります。

  • 関数を処理しません
  • プロパティの順序は重要です
  • 循環参照を処理できません
  • 何が異なるのかについての情報は提供されません

2. より良いオブジェクトの差分を構築する

相違点を検出するだけでなく、何が変更されたのかを通知する、より洗練されたソリューションを作成してみましょう:

function getObjectDiff(original, current) {
  const changes = {};

  // Check current object's properties
  for (const [key, value] of Object.entries(current)) {
    if (!(key in original)) {
      changes[key] = {
        oldValue: undefined,
        newValue: value
      };
      continue;
    }

    const originalValue = original[key];
    const currentValue = value;

    // Handle different types of comparisons
    if (
      originalValue !== currentValue &&
      String(originalValue) !== String(currentValue) &&
      JSON.stringify(originalValue) !== JSON.stringify(currentValue)
    ) {
      changes[key] = {
        oldValue: originalValue,
        newValue: currentValue
      };
    }
  }

  // Check for removed properties
  for (const key of Object.keys(original)) {
    if (!(key in current)) {
      changes[key] = {
        oldValue: original[key],
        newValue: undefined
      };
    }
  }

  return Object.keys(changes).length === 0 ? null : changes;
}

この実装:

  • オブジェクトが同一の場合は null を返します
  • タイプの強制を処理します (例: "30" 対 30)
  • 追加および削除されたプロパティを検出します
  • 詳細な変更情報を提供します

現実世界のアプリケーション

このタイプのオブジェクト比較は、以下の場合に特に役立ちます。

  1. フォーム変更追跡: フォーム内のどのフィールドが変更されたかを検出します
const originalForm = { name: "John", email: "john@example.com" };
const currentForm = { name: "John", email: "john.doe@example.com" };
console.log(getObjectDiff(originalForm, currentForm));
// Output: { email: { oldValue: "john@example.com", newValue: "john.doe@example.com" } }
  1. 状態管理: アプリケーションの状態のどの部分が変化したかを追跡します
  2. API 更新: PATCH リクエストで送信するフィールドを決定します
  3. 監査ログ: データに加えられた特定の変更を記録します

エッジケース (さらに努力する必要がある場合)

  1. ネストされたオブジェクト: 深い比較と浅い比較
  2. 配列: 順序感度と参照比較
  3. 型強制: 文字列と数値の比較
  4. 特別な値: 未定義、null、NaN
  5. パフォーマンス: 大きなオブジェクトの場合、詳細な比較はコストがかかる可能性があります

追記: 2 つのオブジェクトを比較して違いを取得する簡単な関数の Github 要点を次に示します。

以上が2 つのオブジェクトを比較 (diff) する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。