基于key合并JSON数据问题及代码调试求助
基于Key合并JSON数据的问题排查与解决
原始输入数据
[ { "key": 111, "studentInfo": [ { "details": { "calculated_fields": null, "status": false } } ] }, { "key": 222, "studentInfo": [ { "details": { "calculated_fields": null, "status": false } } ] }, { "confidential": { "data": { "access_control": { "private_data": null, "users": [] } }, "key": 111 } }, { "confidential": { "data": { "access_control": { "private_data": null, "users": [] } }, "key": 222 } } ]
期望输出
[ { "key": 111, "studentInfo": [ { "details": { "calculated_fields": null, "status": false } } ], "confidential": { "data": { "access_control": { "private_data": null, "users": [] } }, "key": 111 } }, { "key": 222, "studentInfo": [ { "details": { "calculated_fields": null, "status": false } } ], "confidential": { "data": { "access_control": { "private_data": null, "users": [] } }, "key": 222 } } ]
更新说明:实际不符合预期的输出
[ { "key": 111, "studentInfo": [ { "details": { "calculated_fields": null, "status": false } } ] }, { "confidential": { "data": { "access_control": { "private_data": null, "users": [] } }, "key": 222 } } ]
完整代码
const fs = require("fs"); var util = require('util'); const path = require("path"); const { ObjectFlags } = require('typescript'); const { join } = require('path'); const { stringify } = require('querystring'); const _ = require('lodash'); let rawdata = fs.readFileSync('./sample_data.json'); let jsondata = JSON.parse(rawdata); let stud_records=[]; for (let i = 0; i < jsondata.records.length; i++) { let obj = jsondata.records[i]; let key = obj.id; let studentInfo = jsondata.records[i].data; let data = { studentInfo: [studentInfo], key: key }; stud_records.push(data); } let conf_records=[]; for (let i = 0; i < Object.values(jsondata.conf_data).length; i++) { let obj = Object.values(jsondata.conf_data)[i]; let key = Object.values(jsondata.conf_data)[i].id; let position = i+1; let confidential = Object.values(jsondata.conf_data)[i]; let data = { confidential: { data:confidential, key:key, position: position }, }; conf_records.push(data); } let joined_data= stud_records.concat(conf_records) const merged = Object.values(joined_data.reduce((acc, cur) => { const key = cur.confidential?.key ?? cur.key; if (key) acc[key] = { ...acc[key], ...cur }; return acc; }, {})); var log_file = fs.createWriteStream(__dirname + '/output.json', {flags : 'w'}); var log_stdout = process.stdout; console.log = function(d) { // log_file.write(util.format(d) + '\n'); log_stdout.write(util.format(d) + '\n'); }; console.log(JSON.stringify(merged, null, 2))
问题排查与修正
核心问题分析
- Key类型不匹配:代码中未统一
id的类型,若jsondata.records和jsondata.conf_data中的id一个是数字、一个是字符串,会导致分组Key无法匹配,合并失败。 - 冗余取值操作:
conf_records循环中重复调用Object.values(jsondata.conf_data)[i],既冗余又可能因数组索引变化引发错误。 - 多余字段干扰:添加的
position字段不符合预期输出要求,属于冗余内容。 - 合并逻辑漏洞:当
acc[key]不存在时直接展开undefined,可能导致合并异常。
修正后的代码
const fs = require("fs"); const util = require('util'); // 读取并解析JSON数据 const rawdata = fs.readFileSync('./sample_data.json'); const jsondata = JSON.parse(rawdata); // 处理学生记录,统一Key类型为数字 const stud_records = jsondata.records.map(obj => ({ key: Number(obj.id), studentInfo: [obj.data] })); // 处理保密记录,统一Key类型为数字,移除多余字段 const conf_records = Object.values(jsondata.conf_data).map(obj => ({ confidential: { data: obj, key: Number(obj.id) } })); // 合并两类记录 const joined_data = [...stud_records, ...conf_records]; // 基于Key合并对象 const merged = Object.values(joined_data.reduce((acc, cur) => { const key = cur.confidential?.key ?? cur.key; if (key) { // 确保初始为空对象,避免undefined展开问题 acc[key] = { ...(acc[key] || {}), ...cur }; } return acc; }, {})); // 输出到文件和控制台 const log_file = fs.createWriteStream(__dirname + '/output.json', { flags: 'w' }); const log_stdout = process.stdout; console.log = function(d) { log_file.write(util.format(d) + '\n'); log_stdout.write(util.format(d) + '\n'); }; console.log(JSON.stringify(merged, null, 2));
关键修正点
- 统一Key类型:将
obj.id转为数字,彻底避免类型不匹配导致的分组失败。 - 简化循环逻辑:用
map替代for循环,代码更简洁且减少冗余操作。 - 移除多余字段:删除不符合预期输出的
position字段。 - 完善合并逻辑:初始化空对象确保合并时不会出现
undefined展开的异常。
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

