最近接到一个需求,用户点击两个历史版本然后对每个历史版本的数据的每个字段做对比,如果有的字段数据变化就对变化的字段做高亮显示。如下图:
这是页面的截图,且只能选去两个历史版本,选中两个后不能选去其他历史版本. 重点是两个历史版本分别有两个表格的展示,然后要对比两边表格的不一样,比如虽然两边的表格第一行,但是不一定是一一对应的,双方表格的字段顺序可能是乱序的。这样让我们怎么对比相同部分然后又有双方都独有的字段做单独处理? 我的数据格式是如下:
let arr1 = [
{
id:1,
field1:'xxx',
field2:'xxx'
},
{
id:2
field1:'xxx',
field2:'xxx'
},
];
let arr2 = [
{
id:1
field1:'xxx',
field2:'xxx'
},
{
id:3
field1:'xxx',
field2:'xxx'
},
{
id:4
field1:'xxx',
field2:'xxx'
}
];
如上我们看到两个数组只有一个id为1的一项是一样的,这样我们就需要对比双方数组中共有的这一项,来对比里面的每一个字段是否发生改变。然后再把双方数组中没匹配上的各自做处理。那么思路是什么? 第一步:把两个数组生成map,key值为那个标识为id的,value值就是每一项。 第二步:判断出两个map的size取最大size的那一个并遍历map,拿每一个key来在两个map中找如果双方都有这个可以,那么就可以知道这两个需要对比,判断字段是否改变。然后没遍历一步,只要判断完相同的key之后就把双方map里面的这个key的这一项删除掉。然后双方map生下来的就是自己独有对方没有的字段,然后再单独对这两个剩下的map做遍历,把每一项的字段都标记为变化了。至此就完成任务。下面贴上我个人业务代码:
/**
* @param {version1Obj} 对比的map对象
* @param {version2Obj} 对比的map对象
* @returns {version1Arr, version2Arr} 精确对比过的每个对象
*/
compareMapSize(version1Obj, version2Obj) {
// 判断哪个map的size最大,就以返回哪个map,以它为基础遍历
const mainCompareData = version1Obj.size >= version2Obj.size ? version1Obj : version2Obj;
let version1ObjCopy = lodash.cloneDeep(version1Obj);// version1Obj生成一份独立拷贝
let version2ObjCopy = lodash.cloneDeep(version2Obj);// version2Obj生成一份独立拷贝
let version1Arr = [];
let version2Arr = [];
// 遍历
mainCompareData.forEach((value, key) => {
// 对两个map中共有的key的数据对象做处理
if (version1Obj.get(key) && version2Obj.get(key)) {
let [itemsInfos1, itemsInfos2] = this.compareObject(version1Obj.get(key), version2Obj.get(key));
version1Arr.push(itemsInfos1);
version2Arr.push(itemsInfos2);
// 删除两个map中共有的key
version1ObjCopy.delete(key);
version2ObjCopy.delete(key);
}
});
// 把两个map里面各自没有匹配上的key的值做标记为change字段
version1ObjCopy.size && version1ObjCopy.forEach((value, key) => {
version1Arr.push(this.createValueIsChangeObject(value));
});
version2ObjCopy.size && version2ObjCopy.forEach((value, key) => {
version2Arr.push(this.createValueIsChangeObject(value));
});
return { version1Arr, version2Arr }
},