我有两个对象: oldObj
和 newObj
。
oldObj
中的数据用于填充表单, newObj
是用户更改此表单中的数据并提交它的结果。
两个物体都很深,即。它们具有对象或对象数组等属性 - 它们可以是 n 级深,因此 diff 算法需要是递归的。
现在我不仅需要弄清楚从 oldObj
到 newObj
发生了什么变化(如添加/更新/删除),还需要弄清楚如何最好地表示它。
到目前为止,我的想法是构建一个通用的 genericDeepDiffBetweenObjects
方法,该方法将返回一个 {add:{...},upd:{...},del:{...}}
形式的对象,但后来我想:有人else 之前一定需要这个。
那么……有没有人知道一个库或一段代码可以做到这一点,并且可能有更好的方式来表示差异(以一种仍然是 JSON 可序列化的方式)?
更新:
我想到了一种更好的方法来表示更新的数据,方法是使用与 newObj
相同的对象结构,但将所有属性值转换为表单上的对象:
{type: '<update|create|delete>', data: <propertyValue>}
因此,如果 newObj.prop1 = 'new value'
和 oldObj.prop1 = 'old value'
它将设置 returnObj.prop1 = {type: 'update', data: 'new value'}
更新 2:
当我们得到数组属性时,它变得非常棘手,因为数组 [1,2,3]
应该被视为等于 [2,3,1]
,这对于基于值的类型的数组(如字符串)来说足够简单, int & bool,但是当涉及到引用类型的数组(如对象和数组)时,处理起来非常困难。
应该找到相等的示例数组:
[1,[{c: 1},2,3],{a:'hey'}] and [{a:'hey'},1,[3,{c: 1},2]]
不仅检查这种类型的深度值相等非常复杂,而且找出一种表示可能发生的变化的好方法。
原文由 Martin Jespersen 发布,翻译遵循 CC BY-SA 4.0 许可协议
我写了一个小类,做你想做的,你可以 在这里 测试。
唯一与你的提议不同的是我不考虑
和
相同,因为我认为如果数组元素的顺序不同,则数组不相等。当然,如果需要,这可以更改。此外,此代码可以进一步增强以将函数作为参数,用于根据传递的原始值以任意方式格式化 diff 对象(现在这项工作由“compareValues”方法完成)。