在軟體開發中,經常需要確定兩個物件之間的差異。當處理原始資料類型時,這可能是一個簡單的過程,但當處理包含巢狀屬性、陣列和其他複雜結構的深層物件時,這會變得更加複雜。
我最近遇到這項挑戰並發現通用的深度差異演算法是最有效的方法。這涉及遞歸遍歷兩個對象,比較它們的值,並產生表示差異的結果對象。
為了實現這一點,我開發了以下解決方案:
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... };
為了說明此解決方案,請考慮以下兩個物件:
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') };
運行深度差異對這些物件進行演算法將產生以下結果:
{ 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' } } } } } }
這個結果準確地捕獲了兩個物件之間的差異,表明屬性“b”被刪除,創建了新屬性“c”, 「e」物件有幾個更新和創建的屬性,並且數組「f」經歷了一些更改。
以上是通用的深度比較演算法如何有效地突出具有嵌套屬性、陣列和其他結構的複雜物件之間的差異?的詳細內容。更多資訊請關注PHP中文網其他相關文章!