You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于递归字符串Path实现扁平对象列表到嵌套数组的转换方案咨询

我来帮你搞定这个把扁平path数组转成嵌套结构的问题!不管你用TypeScript/JavaScript还是Kotlin(Android),都有清晰的实现思路,咱们分语言来看:

TypeScript/JavaScript 实现方案

核心思路是先建立path到条目的映射,再通过path的层级关系构建嵌套结构,步骤很清晰:

  1. 创建一个pathMap映射表,把每个条目按path作为key存起来,这样找父节点的时候能快速定位。
  2. 遍历每个条目,拆分它的path得到父级path(比如0001-0001的父path就是0001)。
  3. 如果父级条目存在,就把当前条目加到父级的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的语法特性来实现:

  1. 先定义一个带可变children列表的数据类,方便后续添加子节点。
  2. 用HashMap存储path到条目的映射,实现快速查找。
  3. 遍历每个条目,拆分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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:02:30