如何在javascript中检测JSON的差异



我正在使用gojs库,我必须记录修改了哪个值。(类似Git提交历史(

所以,我想比较JSON并检测哪个密钥被更改了。

示例原始JSON

{
"key01": {
"key01-01": "val01-01",
"key01-02": "val01-02"
},
"key02": {
"key02-01": 0
}
}

示例修改的JSON

{
"key01": {
"key01-01": "val01-01mod"
},
"key02": {
"key02-01": 0,
"key02-02": 1
"key02-03": {
"key02-03-01": 2
}
}
}

比较结果

["key01"]["key01-01"] -> modified
["key01"]["key01-02"] -> removed
["key02"]["key02-02"] -> added
["key02"]["key02-03"] -> added
["key02"]["key02-03"]["key-02-03-01"] -> added

有没有一种好的方法可以用javascript实现这个函数?

您可以对对象进行迭代并进行比较,如果您想以此为起点,我做了一个简单的实现:

const isObject = o => o && typeof o === 'object'
const diffObject = (a, b, prefix = []) => {
const aKeys = Object.keys(a)
const bKeys = Object.keys(b)
const diff = []
for (const key of aKeys) {
if (a[key] === b[key]) continue
if (!(key in b)) {
diff.push({ type: 'removed', key: [...prefix, key] })
continue
}
if (!isObject(a[key]) || !isObject(b[key])) {
diff.push({ type: 'modified', key: [...prefix, key] })
continue
}
diff.push(...diffObject(a[key], b[key], [...prefix, key]))
}
for (const key of bKeys) {
if (key in a) continue
diff.push({ type: 'added', key: [...prefix, key] })
isObject(b[key]) && diff.push(...diffObject({}, b[key], [...prefix, key]))
}
return diff
}
// get the diff
const changes = diffObject({
"key01": {
"key01-01": "val01-01",
"key01-02": "val01-02"
},
"key02": {
"key02-01": 0
}
}, {
"key01": {
"key01-01": "val01-01mod"
},
"key02": {
"key02-01": 0,
"key02-02": 1,
"key02-03": {
"key02-03-01": 2
}
}
})
// print the diff formated
for (const change of changes) {
const formatedKey = change.key.map(k => `[${JSON.stringify(k)}]`).join('')
console.log(formatedKey, '->', change.type)
}

其中一个棘手的部分是处理对象的深度,我将其保存在一个key数组中,该数组保存已遍历对象键的历史记录。

最新更新