基于递归字符串Path实现扁平对象列表到嵌套数组的转换方案咨询
我来帮你搞定这个把扁平path数组转成嵌套结构的问题!不管你用TypeScript/JavaScript还是Kotlin(Android),都有清晰的实现思路,咱们分语言来看:
TypeScript/JavaScript 实现方案
核心思路是先建立path到条目的映射,再通过path的层级关系构建嵌套结构,步骤很清晰:
- 创建一个
pathMap映射表,把每个条目按path作为key存起来,这样找父节点的时候能快速定位。 - 遍历每个条目,拆分它的
path得到父级path(比如0001-0001的父path就是0001)。 - 如果父级条目存在,就把当前条目加到父级的
children数组里;如果找不到父级,说明这是根节点,最后把所有根节点收集起来就是最终的嵌套结构。
代码示例:
// 先定义条目类型,明确结构 interface Item { name: string; type: string; path: string; children?: Item[]; } function flattenToNested(items: Item[]): Item[] { const pathMap = new Map<string, Item>(); const rootItems: Item[] = []; // 第一步:初始化每个条目,给每个条目创建空的children数组并存入映射 items.forEach(item => { const newItem = { ...item, children: [] }; pathMap.set(newItem.path, newItem); }); // 第二步:遍历每个条目,找到父节点并添加到children中 items.forEach(item => { const currentItem = pathMap.get(item.path)!; const pathSegments = item.path.split('-'); // 去掉path的最后一段,得到父级的path const parentPath = pathSegments.slice(0, -1).join('-'); if (parentPath) { const parentItem = pathMap.get(parentPath); parentItem?.children.push(currentItem); } else { // 没有父级path,说明是根节点,加入根列表 rootItems.push(currentItem); } }); return rootItems; } // 测试用例 const input = { "items": [ { "name": "cameras", "type": "group", "path": "0001" }, { "name": "camera-1", "type": "equipment", "path": "0001-0001" }, { "name": "charger", "type": "power", "path": "0001-0001-0001" }, { "name": "cable", "type": "power", "path": "0001-0001-0001-0001" }, { "name": "adapter", "type": "power", "path": "0001-0001-0001-0002" }, { "name": "camera-2", "type": "equipment", "path": "0001-0002" }, { "name": "lights", "type": "group", "path": "0002" } ] }; const nestedResult = flattenToNested(input.items); console.log(JSON.stringify({ items: nestedResult }, null, 2));
Kotlin(Android)实现方案
思路和JS/TS完全一致,只是结合Kotlin的语法特性来实现:
- 先定义一个带可变
children列表的数据类,方便后续添加子节点。 - 用
HashMap存储path到条目的映射,实现快速查找。 - 遍历每个条目,拆分path找到父节点,将当前条目加入父节点的
children,最后收集所有根节点。
代码示例:
// 定义条目数据类,children用可变列表方便修改 data class Item( val name: String, val type: String, val path: String, val children: MutableList<Item> = mutableListOf() ) fun flattenToNested(items: List<Item>): List<Item> { val pathMap = hashMapOf<String, Item>() val rootItems = mutableListOf<Item>() // 第一步:初始化映射,给每个条目创建空的children列表 items.forEach { item -> val newItem = item.copy(children = mutableListOf()) pathMap[newItem.path] = newItem } // 第二步:构建嵌套关系 items.forEach { item -> val currentItem = pathMap[item.path] ?: return@forEach val pathSegments = item.path.split("-") val parentPath = if (pathSegments.size > 1) { pathSegments.dropLast(1).joinToString("-") } else { "" } if (parentPath.isNotEmpty()) { pathMap[parentPath]?.children?.add(currentItem) } else { rootItems.add(currentItem) } } return rootItems } // 测试示例 fun main() { val inputItems = listOf( Item("cameras", "group", "0001"), Item("camera-1", "equipment", "0001-0001"), Item("charger", "power", "0001-0001-0001"), Item("cable", "power", "0001-0001-0001-0001"), Item("adapter", "power", "0001-0001-0001-0002"), Item("camera-2", "equipment", "0001-0002"), Item("lights", "group", "0002") ) val nestedResult = flattenToNested(inputItems) // 可以用Gson或Jackson把结果转成JSON输出 println(nestedResult) }
补充说明
- 这两个方案都支持任意深度的嵌套,只要你的path格式是
xxx-xxx-xxx这种层级结构就能正常工作。 - 如果遇到无效的path(比如某个子节点的父节点不存在),代码会自动忽略,你可以根据业务需求添加对应的错误处理逻辑(比如打印日志或者抛出异常)。
内容的提问来源于stack exchange,提问作者kaplat
相关产品推荐
相关产品推荐

