我见过flitbit/diff,但它说:
简单地记录对数组的更改。我们最关心结构的形状;因此,我们没有时间确定对象是否从阵列中的一个插槽移至另一个插槽....
所以在那儿不行。
您将如何实施?似乎很难。是否可以建立这些现有库之一来忽略数组动作?还是您将如何从头开始直接实现它?
我的用例是,我想跟踪对JSON对象所做的所有更改,以便人们对所做的每次更改都能获得积分/报酬。但是,如果人们只是删除一个数组路径,然后又将其重新添加到用户界面的其他位置,那我就不愿意提出要点了,那很容易:)
我首先尝试考虑展平路径,然后在路径上使用正则表达式,但这似乎行不通:
const flat = require('flat')
const compute = (_a, _b) => {
const a = flat(_a)
const b = flat(_b)
let r_a = []
for (let k_a in a) {
r_a.push([
k_a,
new RegExp(`^` + k_a.replace(/\./g, '\\.').replace(/\d+/g, '\\d+') + `$`)
])
}
let r_b = []
for (let k_b in b) {
r_b.push([
k_b,
new RegExp(`^` + k_b.replace(/\./g, '\\.').replace(/\d+/g, '\\d+') + `$`)
])
}
let diff = []
for (let i = 0, n = r_a.length; i < n; i++) {
let [k_a, r_a_i] = r_a[i]
let matches = false
k_b_loop:
for (let k_b in b) {
if (r_a_i.test(k_b) && a[k_a] === b[k_b]) {
matches = true
break k_b_loop
}
}
if (!matches) {
diff.push({
type: 'remove',
path: k_a
})
}
}
for (let i = 0, n = r_b.length; i < n; i++) {
let [k_b, r_b_i] = r_b[i]
let matches = false
k_a_loop:
for (let k_a in a) {
if (r_b_i.test(k_a) && b[k_b] === a[k_a]) {
matches = true
break k_a_loop
}
}
if (!matches) {
diff.push({
type: 'create',
path: k_b
})
}
}
return diff
}
const test1 = () => {
const a = {
a: [
{ a: 1, b: 2 },
{ a: 1, b: 3 }
],
b: 1,
c: 2
}
const b = {
a: [
{ a: 1, b: 3 },
{ a: 1, b: 1 },
{ a: 1, b: 4 }
],
c: 3
}
const diff = computeDiff(a, b)
console.log(diff)
}
test1()