如何在JavaScript/TypeScript中递归更新嵌套对象的指定值
递归处理多语言嵌套对象转换
问题描述
有如下结构的JSON对象(支持单个对象或同类对象组成的数组):
{ "id": "e8546367-d643-4da0-80dc-0980c9935ded", "offsetSeconds": 86400, "tasks": { "id": "contactChampionInitialTalk", "icon": "0", "skills": [ "skillCommunityManager" ], "name": { "en": "Contact Champion" }, "description": { "en": "Initial talk, agreement on the theme, and potentiel availabilities for the event" } } }
需要将其中所有包含目标语言键(比如en)的嵌套对象,替换为对应语言的值,转换后结构如下:
{ "id": "e8546367-d643-4da0-80dc-0980c9935ded", "offsetSeconds": 86400, "tasks": { "id": "contactChampionInitialTalk", "icon": "0", "skills": [ "skillCommunityManager" ], "name": "Contact Champion", "description":"Initial talk, agreement on the theme, and potentiel availabilities for the event" } }
现有函数仅支持一级结构处理,无法递归处理嵌套层级,需要实现递归版本。
解决方案
递归转换函数实现
我们需要编写一个递归函数,处理对象的所有层级,同时支持数组的遍历处理:
const replaceNestedValuesRecursively = (data: unknown, targetKey: string): unknown => { // 处理数组:遍历每个元素递归转换 if (Array.isArray(data)) { return data.map(item => replaceNestedValuesRecursively(item, targetKey)); } // 处理对象:遍历每个键值对 if (data && typeof data === 'object' && !Array.isArray(data)) { const obj = { ...(data as Record<string, unknown>) }; for (const [key, value] of Object.entries(obj)) { // 如果当前值是包含目标键的对象,替换为对应值 if (value && typeof value === 'object' && !Array.isArray(value) && targetKey in (value as Record<string, unknown>)) { obj[key] = (value as Record<string, unknown>)[targetKey]; } else { // 否则递归处理当前值 obj[key] = replaceNestedValuesRecursively(value, targetKey); } } return obj; } // 非对象/数组类型直接返回 return data; };
函数核心逻辑
- 数组处理:如果传入的是数组,遍历每个元素并递归调用转换函数,确保数组内的每个对象都被处理。
- 对象处理:
- 先浅拷贝原对象,避免修改原始数据。
- 遍历对象的每个键值对:
- 如果当前值是包含目标语言键的对象,直接替换为对应语言的值。
- 如果是其他对象或数组,递归调用函数继续处理嵌套结构。
- 基础类型:字符串、数字等基础类型直接返回,不做修改。
使用示例
处理单个对象
// 原始数据 const originalData = { "id": "e8546367-d643-4da0-80dc-0980c9935ded", "offsetSeconds": 86400, "tasks": { "id": "contactChampionInitialTalk", "icon": "0", "skills": ["skillCommunityManager"], "name": { "en": "Contact Champion" }, "description": { "en": "Initial talk, agreement on the theme, and potentiel availabilities for the event" } } }; // 转换后的数据 const transformedData = replaceNestedValuesRecursively(originalData, 'en'); console.log(transformedData);
运行后会输出目标结构的对象。
处理对象数组
如果输入是数组:
const originalArray = [originalData, { "id": "another-id", "offsetSeconds": 172800, "tasks": { "id": "followUp", "name": { "en": "Follow Up" }, "description": { "en": "Check event preparation progress" } } }]; const transformedArray = replaceNestedValuesRecursively(originalArray, 'en'); console.log(transformedArray);
数组中的每个对象都会被正确转换。
内容的提问来源于stack exchange,提问作者foufrix
相关产品推荐
相关产品推荐

