JS比较两个对象数组的差异
后台传过来一个对象数组,vue渲染到页面中,然后修改了这个对象数组,可能是增删改了其中的某些对象。但是不是操作一下就发到后台去保存,而是只是前端页面在发生变化,最后点击提交按钮的时候才把变化过的数据传到后台去更新。而且后台更新的时候,不是把这整个数组替换成新的,而是改动里面的一部分。所以最后一步发送到后台的时候,前端就需要比较新的对象数组相比于原来的对象数组做了什么操作。然后把这些操作发送到后台。
·
后台传过来一个对象数组,vue渲染到页面中,然后修改了这个对象数组,可能是增删改了其中的某些对象。但是不是操作一下就发到后台去保存,而是只是前端页面在发生变化,最后点击提交按钮的时候才把变化过的数据传到后台去更新。
而且后台更新的时候,不是把这整个数组替换成新的,而是改动里面的一部分。
所以最后一步发送到后台的时候,前端就需要比较新的对象数组相比于原来的对象数组做了什么操作。然后把这些操作发送到后台。
以下是比较的算法,刚开始我是把list1和list2都遍历了一遍,觉得效率低就改为了下面的。
/**
* 判断对象是否为空
* @param obj 对象
* @returns {boolean} 为空返回true,不为空返回false
*/
function isEmptyObj(obj) {
//如果对象的键数组的长度是0,表示为空对象
return Object.keys(obj).length === 0;
}
/**
* 找到两个相同结构的对象的差异内容,并返回包含所有差异的数组
* 注意对象内的值只能是简单类型,复杂类型不考虑
* @param obj1 原对象
* @param obj2 可能修改过的对象
* @returns {{}} 包含所有差异的数组
*/
function findObjOperate(obj1, obj2) {
const resultObj = {};
//遍历obj1的键数组,因为obj1和obj2结构相同,所以不考虑结构上的差异
Object.keys(obj1).forEach(key => {
if (obj1[key] !== obj2[key]) {
//将变化过的属性挂载到返回对象中
resultObj[key] = obj2[key];
}
});
return resultObj;
}
/**
* 找到两个对象数组的差异,并打印从list1到list2的所有变化
* 注意约定id不能修改
* @param list1 原数组
* @param list2 可能修改过的数组
*/
function findOperate(list1, list2) {
//用于记录id值和索引值之间差别的平衡值(以下简称平衡值)
let step = 0;
//遍历list2
list2.forEach((obj2, index) => {
//当前id和平衡过差值后的索引值(以下简称新索引值)还是不等
if (obj2.id !== index + step) {
//当前id和新索引值之间的差值就是被删除对象的个数
for (let j = index + step; j < obj2.id; j++) {
console.log('delete', list1[j]);
}
//更新平衡值
step = obj2.id - index;
}
//根据新索引值在list1中找到对应的对象
const obj1 = list1[index + step];
if (obj1) {
//比较obj1和obj2的差异
const objOperateObj = findObjOperate(obj1, obj2);
//如果返回的对象为空对象,表示没有差异
if (!isEmptyObj(objOperateObj)) {
console.log('modify', obj1.id,objOperateObj);
}
} else {
//js没有下标越界,所以如果obj1是undefined,那么obj2就是新增出的对象
console.log('add', obj2);
}
});
}
用两个对象数组去测试,假设页面数据从user1变成了user2。
const user1 = [{id: 0, name: 'zhangsan', age: 18}, {id: 1, name: 'lisi', age: 19}, {id: 2, name: 'wangwu', age: 20}, {id: 3, name: 'wangwu', age: 20}];
const user2 = [{id: 0, name: 'zhangsan2', age: 19}, {id: 3, name: 'wangwu', age: 20}, {id: 4, name: 'xinren', age: 100}];
findOperate(user1, user2);
打印结果为
modify 0 { name: 'zhangsan2', age: 19 }
delete { id: 1, name: 'lisi', age: 19 }
delete { id: 2, name: 'wangwu', age: 20 }
add { id: 4, name: 'xinren', age: 100 }
从user1到user2,原id为0的对象,name改为了zhangsan2,age改为了19。
原id为1和2的对象被删除。
新增了id为4的对象。
更多推荐
所有评论(0)