问题
I have seen flitbit/diff but it says:
Changes to arrays are recorded simplistically. We care most about the shape of the structure; therefore we don't take the time to determine if an object moved from one slot in the array to another....
So doesn't work there.
How would you implement this? It seems very hard. Is it possible to build off one of these existing libraries to ignore array moves? Or how would you implement it directly from scratch?
My use case is, I want to keep track of all changes made to a JSON object in order that people get points/paid for every change they make. But I don't want to give points if people just delete an array path and then add it back again at a different position in the UI, that would be cheating :)
I started by trying to think of flattening the paths, then using regexes on the paths, but that doesn't seem like it'll work:
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()
来源:https://stackoverflow.com/questions/64635260/how-to-implement-checking-and-ignoring-when-an-array-object-path-is-moved-when