如何将点分数字键的JS对象转为多维数组并实现console分组输出
问题描述
我有如下JavaScript对象:
var numberedList = { "1": "Text of 1", "1.1": ["array of 1.1"], "1.2": { key: "object of 1.2" }, "1.1.1": 999, "1.2.1": true, "1.2.2": function () { return "function of 1.2.2"; }, "1.3": null, "2": 2 }
需要将其转换为对应结构的多维数组,键名对应的层级结构如下:
[ ["1", [ [ [ "1.1", [ "1.1.1" ] ] ], [ [ "1.2", [ "1.2.1", "1.2.2" ] ], ], "1.3" ] ], "2" ]
最终需要输出的数组结构如下:
[ [ "Text of 1", [ [ [ ["array of 1.1"], [ 999 ] ] ], [ [ { key: "object of 1.2" }, [ true, function() { return "function of 1.2.2"; } ] ], ], null ] ], 2 ]
注意最深层级的元素不需要额外包裹数组。需要用纯原生JS编写通用递归函数实现该需求,同时需要基于该对象的层级结构执行console.group()和console.groupEnd()调用,实现控制台层级分组输出。
实现方案
1. 转换为多维数组的通用函数
function buildNestedArray(list) { // 按键的层级顺序排序,保证父节点先处理 const sortedKeys = Object.keys(list).sort((a, b) => a.localeCompare(b, undefined, { numeric: true })); const root = []; // 递归查找/创建对应层级的节点 function resolveNode(segments, currentIndex, parentArr) { const currentSeg = segments[currentIndex]; // 查找当前层级是否已存在对应节点 let targetNode = parentArr.find(item => Array.isArray(item) && item._tempKey === currentSeg); if (!targetNode) { const fullKey = segments.slice(0, currentIndex + 1).join('.'); targetNode = [list[fullKey]]; targetNode._tempKey = currentSeg; parentArr.push(targetNode); } // 处理下一层级 if (currentIndex < segments.length - 1) { targetNode[1] = targetNode[1] || []; resolveNode(segments, currentIndex + 1, targetNode[1]); } return targetNode; } // 遍历所有键构建层级结构 sortedKeys.forEach(key => resolveNode(key.split('.'), 0, root)); // 清理临时标记,移除最底层元素的多余数组包裹 function cleanNode(node) { delete node._tempKey; if (node[1]) node[1] = node[1].map(cleanNode); return node.length === 1 ? node[0] : node; } return root.map(cleanNode); } // 测试调用 console.log(buildNestedArray(numberedList));
2. 控制台层级分组输出实现
如果核心需求是控制台分组输出,不需要先转数组,直接处理更高效:
function printGroupedList(list) { const sortedKeys = Object.keys(list).sort((a, b) => a.localeCompare(b, undefined, { numeric: true })); let lastLevel = 0; sortedKeys.forEach(key => { const level = key.split('.').length; // 关闭层级高于当前的分组 for (let i = lastLevel; i >= level; i--) { console.groupEnd(); } // 打开当前层级分组 console.group(`${key}`, list[key]); lastLevel = level; }); // 关闭所有剩余未关闭的分组 for (let i = lastLevel; i > 0; i--) { console.groupEnd(); } } // 测试调用,打开控制台即可看到分层效果 printGroupedList(numberedList);
内容的提问来源于stack exchange,提问作者kairos
相关产品推荐
相关产品推荐

