接到一个需求,再开发的过程中,发现有一个功能,需要对比json数据,前后的差异,找到新增的数据,删除的数据 ,以及修改的数据。一般来说,咱们只需要找到新增和删除的数据,这里就分享一下,我自己封的一个方法(比较简陋)。
deepClone = (source) => {
if(typeof source === 'function' || typeof source === 'undefined'){
return
}
if(typeof source === 'string'){
return source
}
if(typeof source === 'number'){
return source * 1
}
if(typeof source === 'boolean'){
return new Boolean(source)
}
if(typeof source !== 'object') return;
if(source instanceof RegExp){
return new RegExp(source)
}
if(source instanceof Date){
return new Date(source)
}
const target = (source instanceof Array)?[]:{};
for(let key in source){
if(typeof source[key] === 'object'){
target[key] = deepClone(source[key])
}else{
target[key] = source[key];
}
}
return target
}
因为再使用的时候,传进来的参数,一般都是比较大的json数据,我再使用的时候,发现函数内的某些操作,实际会影响到原始数据,就又写了一个深拷贝,如果你使用的时候,不影响,也就没有必要使用了。
diffArray = (newObj,oldObj,brigedProp) => {
if(typeof newObj !== 'object' || typeof oldObj !== 'object') return
const newSource = deepClone(newObj);
const oldSouce = deepClone(oldObj);
const addElem = []; // 增加的数据
const delElem = []; // 删除的数据
const newSourceIndex = [];
const oldSourceIndex = []; // 存brigedProp相同的情况下新老数组
oldSouce.forEach((elem,oldIndex) => {
oldSourceIndex.push(elem[brigedProp])
});
newSource.forEach((item,newIndex)=> {
newSourceIndex.push(item[brigedProp])
});
newSourceIndex.forEach(item=>{
if(!oldSourceIndex.includes(item)){
addElem.push(newSource.find(itm=>itm[brigedProp] === item))
}
});
oldSourceIndex.forEach(item=>{
if(!newSourceIndex.includes(item)){
delElem.push(oldSouce.find(itm=>itm[brigedProp] === item))
}
});
return {
addElem,
delElem
}
}
这个是简化后的代码,会返回 新增的数据和删除的数据。注意我写的birgedProd,这个是一个字符串,实际就是新旧数据里面的唯一字段,用于对比的。大家要是有其他好的方法,希望能分享一下。
运行的结果图
const news = [
{id:1,name:'zs'},
{id:3,name:'w5'},
{id:4,name:'w5'},
]
const old = [
{id:1,name:'zs'},
{id:2,name:'li'},
{id:3,name:'w5'},
]
const {addElem, delElem} = diffArray(news,old,'id');
console.log(addElem,'addElem');
console.log(delElem,'delElem');