如何在JavaScript中遍历并对比JSON数组与对象数组?
批量对比JSON数据与对象数组的指定字段
问题描述
需要对比一个含50条数据的JSON文件和一个含76条数据的info对象数组,遍历两者并检查指定字段(如TermLoteCupon等)是否匹配。只要有任意一组对应字段不匹配,就返回“文件内容不一致”的错误。当前实现只能匹配单个特定值,无法处理批量数据对比,尝试用for循环但不知道具体操作方式。
原代码问题分析
原代码存在以下核心问题:
- 仅从
infoParsed中提取了第一个存在的字段值(通过map+find),没有遍历所有条目 - 对比逻辑仅针对单个值,未批量检查每一组数据的对应字段
- 未明确两个数组中条目的匹配规则(比如通过哪个字段确定是同一条记录),也未处理数据量不一致的情况
解决方案
核心思路
- 确定匹配规则:通过唯一标识字段(或字段组合)关联两个数组中的同一条记录(比如
TermLoteCupon+Tarj的组合,可根据业务调整) - 定义对比字段列表:处理字段名不一致的情况(比如JSON中的
Fecha del pago和info中的Fecha) - 遍历其中一个数组,对每个条目在另一个数组中找到匹配项,逐一对比指定字段
- 一旦发现不匹配,立即终止遍历并返回错误提示
代码实现
方式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
相关产品推荐
相关产品推荐

