Maison > interface Web > js tutoriel > Comment un algorithme générique de comparaison profonde peut-il mettre en évidence efficacement les différences entre des objets complexes avec des propriétés imbriquées, des tableaux et d'autres structures ?

Comment un algorithme générique de comparaison profonde peut-il mettre en évidence efficacement les différences entre des objets complexes avec des propriétés imbriquées, des tableaux et d'autres structures ?

Susan Sarandon
Libérer: 2024-11-23 09:19:28
original
800 Les gens l'ont consulté

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

Diff profonde générique entre deux objets

Dans le développement de logiciels, il devient souvent nécessaire de déterminer les différences entre deux objets. Cela peut être un processus simple lorsque vous travaillez avec des types de données primitifs, mais devient plus compliqué lorsqu'il s'agit d'objets profonds contenant des propriétés imbriquées, des tableaux et d'autres structures complexes.

Détails de mise en œuvre

J'ai récemment rencontré ce défi et a constaté qu'un algorithme générique de comparaison profonde était l'approche la plus efficace. Cela implique de parcourir récursivement les deux objets, de comparer leurs valeurs et de générer un objet résultat qui représente les différences.

Pour y parvenir, j'ai développé la solution suivante :

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...
};
Copier après la connexion

Exemple d'utilisation

Pour illustrer cette solution, considérons les deux objets suivants :

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')
};
Copier après la connexion

L'exécution de l'algorithme de comparaison profonde sur ces objets produira le résultat suivant :

{
  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' } }
      }
    }
  }
}
Copier après la connexion

Ce résultat capture avec précision les différences entre les deux objets, indiquant que la propriété 'b' a été supprimée, une nouvelle propriété 'c' a été créée, l'objet 'e' a eu plusieurs mises à jour et créé des propriétés, et le tableau 'f' a subi quelques modifications.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal