You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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(新值)的对象数组。

实现步骤

  1. 匹配对应对象:以id为标识,将初始数组和修改后的数组中的对象一一对应,避免因数组顺序变化导致对比错误。
  2. 遍历属性对比:对每一组匹配的对象,遍历其可枚举属性,排除id(作为唯一标识无需对比),判断新旧值是否不同。
  3. 收集变更记录:将所有值不相等的属性整理成要求的格式,收集到结果数组中。

具体代码实现

可以封装一个工具函数来处理对比逻辑,然后在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:37:37