Dalam pembangunan perisian, selalunya menjadi perlu untuk menentukan perbezaan antara dua objek. Ini boleh menjadi proses yang mudah apabila bekerja dengan jenis data primitif, tetapi menjadi lebih rumit apabila berurusan dengan objek dalam yang mengandungi sifat bersarang, tatasusunan dan struktur kompleks lain.
Saya baru-baru ini menemui cabaran ini dan mendapati bahawa algoritma deep diff generik adalah pendekatan yang paling berkesan. Ini melibatkan merentasi kedua-dua objek secara rekursif, membandingkan nilainya dan menjana objek hasil yang mewakili perbezaan.
Untuk mencapai ini, saya membangunkan penyelesaian berikut:
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... };
Untuk menggambarkan penyelesaian ini, pertimbangkan dua perkara berikut objek:
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') };
Menjalankan algoritma deep diff pada objek ini akan menghasilkan hasil berikut:
{ 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' } } } } } }
Hasil ini menangkap dengan tepat perbezaan antara kedua-dua objek, menunjukkan bahawa sifat ' b' telah dipadamkan, sifat baharu 'c' telah dicipta, objek 'e' mempunyai beberapa sifat yang dikemas kini dan dicipta, dan tatasusunan 'f' mengalami beberapa perubahan.
Atas ialah kandungan terperinci Bagaimanakah algoritma perbezaan dalam generik boleh menyerlahkan perbezaan antara objek kompleks dengan sifat bersarang, tatasusunan dan struktur lain dengan berkesan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!