如何遍历存在重复同名键的JSON对象
含重复同名键的JSON对象正确遍历方案
首先明确核心规则:标准JSON规范不推荐对象存在重复同名键,JavaScript原生Object本身有键名唯一性约束。你给出的示例
const res = {"a": {}, "a": {}}在JS引擎初始化对象时,前一个a属性会被后一个直接覆盖,最终res对象只会保留最后一个a对应的空对象,被覆盖的值会直接丢失,不存在任何原生遍历方法可以找回已经丢失的重复键值。
具体处理方案如下:
- 优先推动接口侧修复
带重复键的JSON本身属于不符合规范的输出,存在天然解析歧义:不同语言、不同版本的JSON解析器对重复键的处理逻辑不统一,部分取第一个出现的值、部分取最后一个出现的值,没有统一标准。最稳妥的方案是让接口提供方按照标准规范调整返回结构,将同键名的多组值整合为数组字段,从根源避免解析兼容问题。 - 前端侧自定义解析保留所有重复键值
如果暂时无法推动接口修改,一定不要直接使用默认的JSON.parse()或者前端请求库自带的JSON解析能力处理原始响应,要在接口返回的原始文本阶段做自定义解析,将重复键的所有值聚合到数组结构中再做遍历。简单扁平结构的JSON可以参考如下实现,复杂嵌套JSON建议使用流式JSON解析能力处理,避免正则匹配带来的误差:
// 自定义解析逻辑:重复键的值自动聚合为数组 function parseJsonWithDuplicateKeys(jsonStr) { const result = {}; // 匹配键值对的简易正则,复杂嵌套场景请替换为流式解析逻辑 const keyValueRegex = /"([^"]+)"\s*:\s*(\{[^{}]*\}|\[[^\[\]]*\]|"[^"]*"|-?\d+\.?\d*|null|true|false)/g; let match; while ((match = keyValueRegex.exec(jsonStr)) !== null) { const key = match[1]; let value = match[2]; // 值类型转换 try { value = JSON.parse(value); } catch(e) {} if (Object.prototype.hasOwnProperty.call(result, key)) { // 键已存在时转为数组追加 if (!Array.isArray(result[key])) { result[key] = [result[key]]; } result[key].push(value); } else { result[key] = value; } } return result; } // 调用示例 const rawResponseText = `{"a": {},"a": {}}`; const parsedRes = parseJsonWithDuplicateKeys(rawResponseText); // 解析后 parsedRes.a 为 [{}, {}],保留了所有重复键对应的值
- 解析完成后的遍历方式
经过自定义解析后,重复键对应的值会被整理为标准数组结构,直接使用forEach、for...of、普通for循环等数组遍历方法,即可拿到该键下所有对应的值,不会出现数据丢失。
内容的提问来源于stack exchange,提问作者Naveen Kumar
相关产品推荐
相关产品推荐

