首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测javascript中JSON的差异?

如何检测javascript中JSON的差异?
EN

Stack Overflow用户
提问于 2021-06-23 08:45:41
回答 1查看 39关注 0票数 1

我使用的是gojs库,我必须记录修改了哪个值(比如Git提交历史记录)。

因此,我想要比较JSON并检测哪个键被更改了。

示例原始JSON

代码语言:javascript
复制
{
  "key01": {
    "key01-01": "val01-01",
    "key01-02": "val01-02"
  },
  "key02": {
    "key02-01": 0
  }
}

修改后的JSON示例

代码语言:javascript
复制
{
  "key01": {
    "key01-01": "val01-01mod"
  },
  "key02": {
    "key02-01": 0,
    "key02-02": 1
    "key02-03": {
      "key02-03-01": 2
    }
  }
}

比较结果

代码语言:javascript
复制
["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中实现这个功能的好方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-23 09:28:55

你可以在object上迭代并比较它们,如果你想以此为起点,我做了一个简单的实现:

代码语言: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数组中,该数组保存了遍历对象键的历史记录。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68092213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档