如何将嵌套JSON对象转换为指定的数组结构?
嵌套JSON转树形结构(含parentId、path等属性)
问题背景
需要将嵌套JSON对象转换为指定的树形结构,新增key、title、parentId、id、path、isLeaf、selectable等属性:
原始JSON输入
let jsonObj = { "data": { "cardShop": { "cardData": { "cardTitle": "The Platinum Card<sup>®</sup>", "cardType": "credit-cards", "dtmProductName": "PlatinumCard", "viewAllCards": { "url": "credit-cards/all-cards", "text": "All Cards" } }, "eligibilityChecker": { "header": "Check your eligibility", "subHeader": "The Platinum Card®", "bulletPoints": [ "Only takes a couple of minutes to complete", "Will not impact your credit rating", "Allows you to apply with confidence" ] } } } }
目标树形结构格式
[ { id: "cardShop", key: "cardShop", title: "cardShop", selectable: false, children: [ { id: "cardData", path: "cardShopCardData", key: "cardData", title: "cardData", parentId: "cardShop", selectable: false, children: [ { id: "cardTitle", path: "cardShopcardDatacardTitle", key: "cardTitle", title: "cardTitle", parentId: "cardData", isLeaf: true, children: [] }, { id: "cardType", key: "cardType", title: "cardType", parentId: "cardData", isLeaf: true, children: [] }, { id: "dtmProductName", key: "dtmProductName", title: "dtmProductName", parentId: "cardData", isLeaf: true, children: [] }, { id: "viewAllCards", key: "viewAllCards", title: "viewAllCards", parentId: "cardData", selectable: false, children: [ { id: "url", key: "url", title: "url", parentId: "viewAllCards", isLeaf: true, }, { id: "text", key: "text", title: "text", parentId: "viewAllCards", isLeaf: true, } ] } ] }, { id: "eligibilityChecker", key: "eligibilityChecker", title: "eligibilityChecker", parentId: "cardShop", selectable: false, children: [ { id: "header", key: "header", title: "header", parentId: "eligibilityChecker", isLeaf: true, children: [] }, { id: "subHeader", key: "subHeader", title: "subHeader", parentId: "eligibilityChecker", isLeaf: true, children: [] }, { id: "bulletPoints", key: "bulletPoints", title: "bulletPoints", parentId: "eligibilityChecker", isLeaf: true, children: [] } ] } ] } ];
尝试的代码(未得到预期结果)
let prevKey ="" const iterate = (obj) => { Object.keys(obj).forEach(key => { if (typeof obj[key] === 'object' && obj[key] !== null) { let c ={ id:key, title:key, selelected:false, children:[] }; if(prevKey && Object.keys(output).length === 0){ output ={ children :[] } output.children.push(c) } else if(prevKey ){ output.children.push(c) } else{ output = c } prevKey = key; iterate(obj[key]) } else{ let c ={ id:key, title:key, selelected:false, children:[] }; output.children[0].children.push(c) } }) }
解决方案
核心思路是递归遍历每个节点,同时传递父节点ID、当前路径前缀等上下文信息,区分叶子节点(值为非对象/数组类型)和非叶子节点(值为对象类型),为每个节点添加对应属性。
完整转换代码
// 递归转换函数 const transformToTree = (obj, parentId = '', pathPrefix = '') => { return Object.keys(obj).map(key => { const currentPath = pathPrefix ? `${pathPrefix}${key}` : key; const node = { id: key, key: key, title: key, parentId: parentId, children: [] }; const value = obj[key]; // 判断是否为叶子节点:值不是对象/数组,或者是数组、null const isLeaf = typeof value !== 'object' || value === null || Array.isArray(value); if (isLeaf) { node.isLeaf = true; node.path = currentPath; } else { node.selectable = false; node.path = currentPath; // 递归处理子节点,传递当前key作为父ID、当前路径作为前缀 node.children = transformToTree(value, key, currentPath); } return node; }); }; // 调用转换函数(取原始JSON的data字段内容) const result = transformToTree(jsonObj.data); console.log(JSON.stringify(result, null, 2));
代码说明
- 递归参数:
obj为当前处理的对象,parentId传递父节点ID,pathPrefix用于拼接生成节点的path属性。 - 基础属性生成:每个节点默认生成
id、key、title、parentId、children属性。 - 叶子节点处理:当节点值为非对象、null或数组时,标记为叶子节点(
isLeaf: true),不再递归子节点。 - 非叶子节点处理:添加
selectable: false属性,递归处理子对象并赋值给children。 - 路径拼接:通过父路径前缀+当前key生成节点的
path属性。
内容的提问来源于stack exchange,提问作者K.S
相关产品推荐
相关产品推荐

