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.
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... };
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') };
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' } } } } } }
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!