如何重命名对象数组中的重复键并为其添加递增整数后缀
问题解决方法
前置注意
注意:标准JavaScript和JSON规范中,对象的字符串键具备唯一性,直接使用JSON.parse解析你给出的输入样例时,后出现的重复键会直接覆盖前序同键的值,造成数据丢失。因此处理时必须先从原始文本层面提取所有按出现顺序排列的键值对,不能直接使用默认JSON解析的结果。
针对预期输出的实现逻辑
你给出的预期输出本质是按键值对的出现位置跨对象重组,处理步骤如下:
- 将原始数组里每个对象的键值对按书写顺序拆为有序列表,保留所有重复键对应的值
- 校验所有原始对象的键值对总数一致(你的样例里每个对象都包含2个键值对)
- 初始化结果数组,长度等于单个原始对象的键值对数量,每一项初始为空对象
- 遍历所有原始对象的键值对列表,将第
i位的键值对写入结果数组第i项的对应键名下 - 遍历完成后得到的结果数组就和预期输出完全匹配
可运行代码示例
// 注意:这里直接传入原始输入文本,不要提前调用JSON.parse const rawInput = `[ { "test1": {}, "test1": {} }, { "test2": {}, "test2": {} } ]`; // 解析函数:提取所有对象块内的键值对,保留重复键 function parseRawKeepDuplicateKeys(rawStr) { const objectBlocks = rawStr.match(/\{[\s\S]*?\}/g) || []; return objectBlocks.map(block => { const kvPairs = []; const kvMatchRegex = /"(\w+)":\s*(\{\}|\[\]|null|true|false|\d+|".*?")/g; let matchRes; while ((matchRes = kvMatchRegex.exec(block)) !== null) { kvPairs.push({ key: matchRes[1], rawValue: matchRes[2] }); } return kvPairs; }); } const parsedKvGroup = parseRawKeepDuplicateKeys(rawInput); const resultLength = parsedKvGroup[0].length; const result = Array.from({ length: resultLength }, () => ({})); // 按位置重组键值对 parsedKvGroup.forEach(kvList => { kvList.forEach((kv, position) => { result[position][kv.key] = JSON.parse(kv.rawValue); }); }); console.log(result); /* 输出: [ { test1: {}, test2: {} }, { test1: {}, test2: {} } ] 完全匹配预期结果 */
补充:单对象内重复键加递增后缀的实现
如果你不需要跨对象重组,只是要把单个对象里的重复键重命名为原键名_递增序号的格式,可以用下面的处理逻辑:
function addSuffixForDuplicateKeys(kvList) { const keyCounter = new Map(); const formattedObj = {}; kvList.forEach(kv => { const currentCount = keyCounter.get(kv.key) || 0; const finalKey = currentCount === 0 ? kv.key : `${kv.key}_${currentCount}`; formattedObj[finalKey] = JSON.parse(kv.rawValue); keyCounter.set(kv.key, currentCount + 1); }); return formattedObj; } // 调用后每个原对象会被处理为 { test1: {}, test1_1: {} } 的结构 const suffixRenamedResult = parsedKvGroup.map(addSuffixForDuplicateKeys);
内容的提问来源于stack exchange,提问作者SP-
相关产品推荐
相关产品推荐

