如何在JavaScript嵌套对象数组的子对象中添加新键值对?
如何给嵌套对象数组中的每个rules子对象添加temp_id属性
我需要在_this.existingConfigurations这个嵌套对象数组中,为每个元素的rules数组内的所有子对象动态添加temp_id属性。现有数组结构如下:
[ { "featureId": "67d6e1bf-3919-4dcc-b636-236ab41d431b", "featureName": "Test name 1", "rules": [ { "ruleId": "a9ab3ce2-e69c-4c0c-b561-1107baed1e68", "ruleName": "Sub test 1" }, { "ruleId": "a9ab3ce2-e69c-4c0c-b561-1107baed1e68", "ruleName": "Sub Test 2" }, { "ruleId": "a8003493-4471-4c8a-85c1-b15706359bb3", "ruleName": "Sub Test Three" } ] }, // 更多类似对象... ]
期望输出是每个rules子对象都新增temp_id属性(示例中用1,实际可以是uuid或自增id):
[ { "featureId": "67d6e1bf-3919-4dcc-b636-236ab41d431b", "featureName": "Test name 1", "rules": [ { "ruleId": "a9ab3ce2-e69c-4c0c-b561-1107baed1e68", "ruleName": "Sub test 1", "temp_id": 1 }, { "ruleId": "a9ab3ce2-e69c-4c0c-b561-1107baed1e68", "ruleName": "Sub Test 2", "temp_id": 1 }, { "ruleId": "a8003493-4471-4c8a-85c1-b15706359bb3", "ruleName": "Sub Test Three", "temp_id": 1 } ] }, // 更多类似对象... ]
我尝试了下面的代码但没达到预期效果:
Object.keys(_this.existingConfigurations).map((key)=>_this.existingConfigurations[key].rules).reduce((n,id)=>n).map((ny,ni)=>{return {...ny, temp_id : uuid.v4()}});
原代码问题分析
_this.existingConfigurations是数组,用Object.keys()处理完全多余,直接遍历数组即可。- 代码提取所有元素的
rules数组后,用reduce((n,id)=>n)的逻辑错误——没有传入初始值时,会取第一个rules数组作为初始值,后续迭代都返回这个初始值,最终只拿到第一个配置项的rules数组。 - 最后
map生成的带temp_id的新对象,没有放回原数组的rules字段中,原数组完全没被修改,自然看不到效果。
解决方案
方案1:原地修改原数组
如果不需要保留原数组的原始状态,可以直接遍历更新:
// 遍历每个配置项 _this.existingConfigurations.forEach(config => { // 遍历当前配置项的所有rules,添加temp_id config.rules.forEach(rule => { rule.temp_id = uuid.v4(); // 用uuid生成唯一值,也可以替换为自增数等 }); });
方案2:生成新数组(不修改原数组)
如果需要保留原数组不变,生成全新的数组对象:
const updatedConfigurations = _this.existingConfigurations.map(config => { return { ...config, // 复制原配置项的其他属性 rules: config.rules.map(rule => ({ ...rule, // 复制原rule的属性 temp_id: uuid.v4() })) }; }); // 将updatedConfigurations传递给下一环节使用
补充:同一ruleId对应相同temp_id
如果需要相同ruleId的子对象使用同一个temp_id,可以维护一个映射表:
const ruleIdMap = new Map(); let tempIdCounter = 1; const updatedConfigurations = _this.existingConfigurations.map(config => ({ ...config, rules: config.rules.map(rule => { if (!ruleIdMap.has(rule.ruleId)) { ruleIdMap.set(rule.ruleId, tempIdCounter++); } return { ...rule, temp_id: ruleIdMap.get(rule.ruleId) }; }) }));
内容的提问来源于stack exchange,提问作者Sathishkumar
相关产品推荐
相关产品推荐

