在软件开发中,经常需要确定两个对象之间的差异。当处理原始数据类型时,这可能是一个简单的过程,但当处理包含嵌套属性、数组和其他复杂结构的深层对象时,这会变得更加复杂。
我最近遇到这一挑战并发现通用的深度差异算法是最有效的方法。这涉及递归遍历两个对象,比较它们的值,并生成表示差异的结果对象。
为了实现这一点,我开发了以下解决方案:
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中文网其他相关文章!