我见过
flitbit/diff
但上面说:
对数组的更改被简单地记录下来。我们最关心的是结构的形状;因此,我们不会花时间来确定对象是否从阵列中的一个插槽移动到另一个插槽。。。。
所以在那里不起作用。
你将如何实现这一点?看起来很难。有没有可能构建一个现有的库来忽略数组
? 或者,您将如何从零开始直接实现它?
我的用例是,我想跟踪对JSON对象所做的所有更改,以便人们为他们所做的每一个更改获得积分/报酬。但我不想给点,如果人们只是删除一个数组路径,然后在UI中的不同位置重新添加它,那将是欺骗:)
我开始想
路径,然后在路径上使用正则表达式,但这似乎不起作用:
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()