React中如何比较两个对象数组并获取差异值(用于变更日志)
在React中实现变更日志对比功能
给定初始数据数组initArray:
[ { "id": 1, "val1": "2023-08-28", "val2": 1, "val3": "", "val4": "", }, { "id": 2, "val1": "2023-08-28", "val2": 2, "val3": "", "val4": "" }, { "id": 3, "val1": "2023-08-28", "val2": 0, "val3": "", "val4": "" } ]
以及修改后的数组changedArray:
[ { "id": 1, "val1": "2023-08-28", "val2": 1, "val3": "test", "val4": "test1" }, { "id": 2, "val1": "2023-08-28", "val2": 2, "val3": "test2", "val4": "test3" }, { "id": 3, "val1": "2023-08-28", "val2": 0, "val3": "", "val4": "" } ]
需求是找出所有属性值的变更,输出格式为包含changedValue(属性名)、previousValue(旧值)、newValue(新值)的对象数组。
实现步骤
- 匹配对应对象:以
id为标识,将初始数组和修改后的数组中的对象一一对应,避免因数组顺序变化导致对比错误。 - 遍历属性对比:对每一组匹配的对象,遍历其可枚举属性,排除
id(作为唯一标识无需对比),判断新旧值是否不同。 - 收集变更记录:将所有值不相等的属性整理成要求的格式,收集到结果数组中。
具体代码实现
可以封装一个工具函数来处理对比逻辑,然后在React组件中调用:
import { useEffect, useState } from 'react'; // 对比两个数组,生成变更日志 const generateChangeLog = (initArray, changedArray) => { const changeLog = []; // 将初始数组转成以id为键的对象,方便快速查找匹配项 const initObjMap = initArray.reduce((map, item) => { map[item.id] = item; return map; }, {}); // 遍历修改后的数组,对比对应初始对象 changedArray.forEach(changedItem => { const initItem = initObjMap[changedItem.id]; if (!initItem) return; // 遍历当前对象的所有属性 Object.keys(changedItem).forEach(key => { // 跳过id属性 if (key === 'id') return; const oldVal = initItem[key]; const newVal = changedItem[key]; // 对比值是否不同(简单类型直接用===,复杂类型需深对比) if (oldVal !== newVal) { changeLog.push({ changedValue: key, previousValue: oldVal, newValue: newVal }); } }); }); return changeLog; }; // 示例React组件 function ChangeLogDemo() { const [changeLog, setChangeLog] = useState([]); useEffect(() => { // 替换为实际的初始数组和修改后数组 const initArray = [ { "id": 1, "val1": "2023-08-28", "val2": 1, "val3": "", "val4": "" }, { "id": 2, "val1": "2023-08-28", "val2": 2, "val3": "", "val4": "" }, { "id": 3, "val1": "2023-08-28", "val2": 0, "val3": "", "val4": "" } ]; const changedArray = [ { "id": 1, "val1": "2023-08-28", "val2": 1, "val3": "test", "val4": "test1" }, { "id": 2, "val1": "2023-08-28", "val2": 2, "val3": "test2", "val4": "test3" }, { "id": 3, "val1": "2023-08-28", "val2": 0, "val3": "", "val4": "" } ]; const log = generateChangeLog(initArray, changedArray); setChangeLog(log); }, []); return ( <div> <h3>变更日志</h3> <ul> {changeLog.map((item, index) => ( <li key={index}> 属性 <strong>{item.changedValue}</strong>:从「{item.previousValue}」变为「{item.newValue}」 </li> ))} </ul> </div> ); } export default ChangeLogDemo;
注意事项
- 如果需要对比复杂数据类型(如对象、数组),不能直接用
!==,需要实现深对比逻辑,或者使用成熟的工具方法(如lodash的isEqual)来判断值是否真正不同。 - 如果确定两个数组的元素顺序完全一致,也可以直接按索引遍历对比,但用
id匹配的方式兼容性更强,适合数组顺序可能变化的场景。
内容的提问来源于stack exchange,提问作者Quribe
相关产品推荐
相关产品推荐

