我使用的是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中实现这个功能的好方法?
发布于 2021-06-23 09:28:55
你可以在object上迭代并比较它们,如果你想以此为起点,我做了一个简单的实现:
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数组中,该数组保存了遍历对象键的历史记录。
https://stackoverflow.com/questions/68092213
复制相似问题