簡體   English   中英

如何檢測 javascript 中 JSON 的差異?

[英]How can I detect differences of JSON in javascript?

我正在使用 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數組中,該數組保留了遍歷對象鍵的歷史記錄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM