js树结构对象比对
最近项目开发中遇到一个很有意思的需求,两组对象深度对比,并记录出改变的值,本菜鸡大体实现了一下
一、比对的数据
示例:下面展示一下测试用数据。
// 两组树结构数据,用于比对测试
let res1 = {
initData: {
props: '数据',
provide: '传入',
inject: '传出',
emit: 111,
attr: {
input:'111',
checked: {
radio:1
}
}
},
domData: {
attr: '属性',
selecter: '选择器',
firstName: {
input:'222',
timeBox:'222',
name: 123,
lastName: {
name: 111
}
},
children: [
{
test1: 111,
test2: 222,
id: 15,
test: {
id: 123
}
}
]
},
}
let res2 = {
initData: {
props: '数据1',
provide: '传入',
inject: '传出',
emit: 111,
attr: {
checked: {
radio:2
}
}
},
domData: {
listener: '111',
selecter: '选择器',
firstName: {
name: 111,
lastName: {
name: 222
}
},
children: [
{
test1: 111,
test2: 222,
id: 15,
test: {
id: 111
}
}
]
},
}
二、js代码如下
下面展示一下js代码 属性为null的默认不处理当作不存在
。
// 比对
function diff(o1, o2, arrow = "->") {
if (typeof o1 !== 'object' && typeof o2 !== 'object') return
if ((o1 === null || o2 === null) || (o1 === o2)) return
// 处理数组的差异,差异一起放在一个新的数组中
function diffArray(arr1, arr2) {
const a1 = JSON.parse(JSON.stringify(arr1))
const a2 = JSON.parse(JSON.stringify(arr2))
for (let i = a1.length - 1; i >= 0; i--) {
const str = JSON.stringify(a1[i])
if (arr2.length === 0) break
for (let j = a2.length - 1; j >= 0; j--) {
if (JSON.stringify(a2[j]) == str) {
arr2.splice(j, 1)
a2.splice(j, 1)
arr1.splice(i, 1)
break;
}
}
}
return arr1.concat(arr2)
}
// 处理对象的差异
function diffObject(obj1, obj2, flag) {
// 最终要返回的差异对象
const r = {}
for (const k in obj1) {
if (typeof obj1[k] === "object" && obj1[k] !== null) {
if (Array.isArray(obj1[k])) {
const end = diffArray(obj1[k], obj2[k])
end.length && (r[k] = end)
} else {
let end = Object.assign(diffObject(obj2[k], obj1[k], true), diffObject(obj1[k], obj2[k], false))
if (JSON.stringify(end) !== "{}") r[k] = end;
}
} else {
if (obj1[k] !== obj2[k]) {
// 记录是修改还是更新还是删除
let type = "update";
if (obj2[k] === undefined || obj1[k] === undefined) {
type = flag ? obj2[k] === undefined ? 'add' : 'delete' : obj1[k] === undefined ? 'add' : 'delete'
}
r[k] = flag ? `${type}: ${JSON.stringify(obj2[k]) + arrow + JSON.stringify(obj1[k])}` : `${type}: ${JSON.stringify(obj1[k]) + arrow + JSON.stringify(obj2[k])}`
}
}
}
return r;
}
// 返回最终处理完差异的对象结构
return Object.assign(diffObject(o2, o1, true), diffObject(o1, o2, false))
}
三、比对后的结果展示
下面展示一下控制台输出的结果
总结
数组的比对还没有想到好的展示效果,暂时先简单处理一下,第一次发博客,记录一下本菜鸡的前端学习路线和经验。