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

JavaScript中对比两个对象数组,如何获取变更行索引与属性?

对比动态对象数组获取变更行及属性的解决方案

问题场景

我从API获取两个动态对象数组(字段由终端用户创建,预先未知键名),一个为原数组,另一个是修改后的版本。需要对比这两个数组,获取修改后数组中变更的rowIndex以及具体变更的对象属性。现有代码只能获取到对象本身,无法得到changedKeys,期望输出如下格式的结果:

[
    {
        "rowIndex": 1,
        "changedKeys": ["model"]
    },
    {
        "rowIndex": 3,
        "changedKeys": ["brand", "model"]
    }
]

原代码示例

const originalData = [{
  brand: 'Honda',
  model: 'Accord'
}, {
  brand: 'Honda',
  model: 'Civic'
}, {
  brand: 'Toyota',
  model: 'Camry'
}, {
  brand: 'Toyota',
  model: 'Corolla'
}]

const data = [{
  brand: 'Honda',
  model: 'Accord'
}, {
  brand: 'Honda',
  model: 'CRV'
}, {
  brand: 'Toyota',
  model: 'Camry'
}, {
  brand: 'Nissan',
  model: 'RAV4'
}]


console.log(data.reduce((a, c, i, arr) => {
  if (!originalData.some(j => {
      return _.isEqual(c, j)
    })) {
    a.push({
      rowIndex: i,
      changedKeys: arr[i]
    })
  }
  return a
}, []))

解决方案代码

const originalData = [{
  brand: 'Honda',
  model: 'Accord'
}, {
  brand: 'Honda',
  model: 'Civic'
}, {
  brand: 'Toyota',
  model: 'Camry'
}, {
  brand: 'Toyota',
  model: 'Corolla'
}]

const data = [{
  brand: 'Honda',
  model: 'Accord'
}, {
  brand: 'Honda',
  model: 'CRV'
}, {
  brand: 'Toyota',
  model: 'Camry'
}, {
  brand: 'Nissan',
  model: 'RAV4'
}]

const changes = data.reduce((acc, currentObj, index) => {
  const originalObj = originalData[index];
  
  // 原数组无对应行时,直接收集当前对象所有键
  if (!originalObj) {
    acc.push({
      rowIndex: index,
      changedKeys: Object.keys(currentObj)
    });
    return acc;
  }
  
  // 合并两个对象的所有键,避免遗漏新增/删除的属性
  const allKeys = new Set([...Object.keys(originalObj), ...Object.keys(currentObj)]);
  const changedKeys = [];
  
  // 遍历所有键,对比值是否变更
  for (const key of allKeys) {
    if (!_.isEqual(originalObj[key], currentObj[key])) {
      changedKeys.push(key);
    }
  }
  
  // 存在变更时才加入结果
  if (changedKeys.length > 0) {
    acc.push({
      rowIndex: index,
      changedKeys
    });
  }
  
  return acc;
}, []);

console.log(changes);

代码说明

  1. 同索引行对比:默认数组行顺序不变,直接取原数组对应索引的对象进行对比(若业务中存在行排序变化,需先通过唯一标识匹配对应行再对比)。
  2. 全键覆盖:用Set合并原对象与当前对象的所有键,确保不会遗漏新增或删除的属性。
  3. 深度值对比:借助_.isEqual实现深度对比,支持嵌套对象等复杂类型的变更判断。
  4. 结果过滤:仅收集存在属性变更的行,避免无意义的空数据。

运行后输出与期望格式完全一致。

内容的提问来源于stack exchange,提问作者arunmmanoharan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:55:20