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

如何在JavaScript中遍历并对比JSON数组与对象数组?

批量对比JSON数据与对象数组的指定字段

问题描述

需要对比一个含50条数据的JSON文件和一个含76条数据的info对象数组,遍历两者并检查指定字段(如TermLoteCupon等)是否匹配。只要有任意一组对应字段不匹配,就返回“文件内容不一致”的错误。当前实现只能匹配单个特定值,无法处理批量数据对比,尝试用for循环但不知道具体操作方式。

原代码问题分析

原代码存在以下核心问题:

  • 仅从infoParsed中提取了第一个存在的字段值(通过map+find),没有遍历所有条目
  • 对比逻辑仅针对单个值,未批量检查每一组数据的对应字段
  • 未明确两个数组中条目的匹配规则(比如通过哪个字段确定是同一条记录),也未处理数据量不一致的情况

解决方案

核心思路

  1. 确定匹配规则:通过唯一标识字段(或字段组合)关联两个数组中的同一条记录(比如TermLoteCupon+Tarj的组合,可根据业务调整)
  2. 定义对比字段列表:处理字段名不一致的情况(比如JSON中的Fecha del pago和info中的Fecha)
  3. 遍历其中一个数组,对每个条目在另一个数组中找到匹配项,逐一对比指定字段
  4. 一旦发现不匹配,立即终止遍历并返回错误提示

代码实现

方式1:嵌套循环(适合小数据量场景)

const fs = require('fs');

// 读取并解析JSON文件
const data = fs.readFileSync("../api/src/routes/prueba.json");
const jsonData = JSON.parse(data);
// 兼容JSON顶层是数组或含Transacción属性的对象两种格式
const jsonItems = Array.isArray(jsonData) ? jsonData : jsonData.Transacción;

// 定义对比字段映射:JSON字段名 => info数组字段名(字段名一致时直接写字符串)
const compareFields = {
  TermLoteCupon: 'TermLoteCupon',
  Tarj: 'Tarj',
  Trx: 'Trx',
  'Fecha del pago': 'Fecha' // 处理字段名不一致的情况
};

// 批量对比函数
function compareData(jsonArr, infoArr) {
  // 遍历JSON数组的每个条目
  for (const jsonItem of jsonArr) {
    // 在info数组中找到匹配条目(用TermLoteCupon+Tarj作为唯一标识)
    const matchedInfoItem = infoArr.find(infoItem => 
      infoItem.TermLoteCupon === jsonItem.TermLoteCupon && infoItem.Tarj === jsonItem.Tarj
    );

    // 找不到匹配条目直接返回错误
    if (!matchedInfoItem) {
      return "文件内容不一致:未找到匹配的记录";
    }

    // 逐一对比指定字段
    for (const [jsonField, infoField] of Object.entries(compareFields)) {
      const jsonValue = jsonItem[jsonField];
      const infoValue = matchedInfoItem[infoField];

      if (jsonValue !== infoValue) {
        return `文件内容不一致:字段${jsonField}值不匹配,JSON值为${jsonValue},info值为${infoValue}`;
      }
    }
  }

  return "所有数据字段匹配一致";
}

// 执行对比并输出结果
const result = compareData(jsonItems, info);
console.log(result);

方式2:Map索引优化(适合大数据量场景)

如果数据量较大,嵌套循环效率较低,可以先将info数组用唯一标识构建索引Map,再遍历对比:

const fs = require('fs');

const data = fs.readFileSync("../api/src/routes/prueba.json");
const jsonData = JSON.parse(data);
const jsonItems = Array.isArray(jsonData) ? jsonData : jsonData.Transacción;

const compareFields = {
  TermLoteCupon: 'TermLoteCupon',
  Tarj: 'Tarj',
  Trx: 'Trx',
  'Fecha del pago': 'Fecha'
};

function compareData(jsonArr, infoArr) {
  // 构建info数组的索引Map,key为唯一标识(TermLoteCupon+Tarj)
  const infoMap = new Map();
  for (const item of infoArr) {
    const key = `${item.TermLoteCupon}_${item.Tarj}`;
    infoMap.set(key, item);
  }

  // 遍历JSON数组
  for (const jsonItem of jsonArr) {
    const key = `${jsonItem.TermLoteCupon}_${jsonItem.Tarj}`;
    const matchedInfoItem = infoMap.get(key);

    if (!matchedInfoItem) {
      return "文件内容不一致:未找到匹配的记录";
    }

    for (const [jsonField, infoField] of Object.entries(compareFields)) {
      if (jsonItem[jsonField] !== matchedInfoItem[infoField]) {
        return `文件内容不一致:字段${jsonField}值不匹配,JSON值为${jsonItem[jsonField]},info值为${matchedInfoItem[infoField]}`;
      }
    }
  }

  return "所有数据字段匹配一致";
}

const result = compareData(jsonItems, info);
console.log(result);

注意事项

  • 唯一标识选择:如果TermLoteCupon本身是唯一的,可单独作为key;否则需组合多个字段确保匹配准确性
  • 字段名兼容:若两个数据源字段名不同,需在compareFields中做映射处理
  • 双向检查:如果需要验证info数组的所有条目也在JSON中存在,可在函数中添加反向遍历逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 06:35:19