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

JavaScript数据结构反转与去重求助:多层Topic嵌套转换

问题:嵌套Topic数据结构的层级反转与去重

输入数据结构

const data = [
    {
        "id": 1,
        "attributes": {
            "name": "Mother of All Topics",
            "info": "Notice",
            "parentTopic": {
                "data": null
            }
        }
    },
    // 其余数据省略
];

现有尝试的递归函数

// 生成前缀
const getPrefix = (prefix, i) =>
  prefix ? `${prefix}.${i + 1}` : `${i + 1}`;

// 反转层级
const invertHierarchy = (arr, parentTopic, prefix) =>
  arr
    .filter((e) => e.parentTopic.data?.id === parentTopic)
    .map((e, i) => ({
      ...e,
      index: getPrefix(prefix, i),
      topics: invertHierarchy(arr, e.id, getPrefix(prefix, i)),
    }));

该函数仅支持一层嵌套,无法处理多层嵌套场景,也未覆盖输入中嵌套父节点的收集与节点去重需求。

目标输出结构

[
    {
        "id": 1,
        "name": "Mother of All Topics",
        "topics": [
            {
                "id": 2,
                "name": "Important Topic",
                "info": null,
                "topics": [
                    {
                        "id": 3,
                        "name": "Critical Topic",
                        "topics": []
                    }
                ]
            }
        ]  
    },
    // 其余结构省略
]

更新后的输入输出示例

更新输入

const updatedData = [
    {
        "id": 25,
        "attributes": {
            "name": "Nice Topic",
            "info": "",
            "parentTopic": {
                "data": {
                    "id": 24,
                    "attributes": {
                        "name": "Critical Top Level",
                        "info": "",
                        "parentTopic": {
                            "data": null
                        }
                    }
                }
            }
        }
    },
    // 其余数据省略
];

期望输出

[
    {
        "id": 24,
        "name": "Critical Top Level",
        "info": "",
        "topics": [
            {
                "id": 25,
                "name": "Nice Topic",
                "info": "",
                "topics": []
            }
        ]
    },
    // 其余结构省略
]

核心需求

  • 将含嵌套父节点的扁平Topic数据转换为层级结构,父节点位于顶层,子节点嵌套在topics数组中
  • 自动收集所有嵌套的父节点,避免丢失
  • 基于id对节点去重
  • 支持任意层级的嵌套

解决方案

实现思路

  1. 扁平化收集所有节点:遍历输入数据,递归收集嵌套在parentTopic.data中的所有节点,用Map存储以实现去重
  2. 构建父子关系映射:遍历所有节点,记录每个节点的子节点列表
  3. 递归生成层级结构:从顶层节点(parentTopic.data为null)开始,递归转换每个节点为目标格式

代码实现

// 扁平化收集所有节点(含嵌套父节点)并去重
const collectAllNodes = (items, nodeMap = new Map()) => {
    items.forEach(item => {
        if (!nodeMap.has(item.id)) {
            nodeMap.set(item.id, item);
        }
        const parentData = item.attributes.parentTopic.data;
        if (parentData) {
            collectAllNodes([parentData], nodeMap);
        }
    });
    return Array.from(nodeMap.values());
};

// 构建层级结构
const buildHierarchy = (nodes) => {
    const nodeMap = new Map();
    const childrenMap = new Map();

    nodes.forEach(node => {
        nodeMap.set(node.id, node);
        if (!childrenMap.has(node.id)) {
            childrenMap.set(node.id, []);
        }
        const parentId = node.attributes.parentTopic.data?.id;
        if (parentId !== undefined) {
            if (!childrenMap.has(parentId)) {
                childrenMap.set(parentId, []);
            }
            childrenMap.get(parentId).push(node);
        }
    });

    const buildNode = (node) => {
        const { id, attributes: { name, info } } = node;
        return {
            id,
            name,
            info: info ?? null,
            topics: (childrenMap.get(id) || []).map(child => buildNode(child))
        };
    };

    return nodes
        .filter(node => node.attributes.parentTopic.data === null)
        .map(node => buildNode(node));
};

// 主函数:整合流程
const invertTopicHierarchy = (inputData) => {
    const allNodes = collectAllNodes(inputData);
    return buildHierarchy(allNodes);
};

// 使用示例
const result = invertTopicHierarchy(updatedData);
console.log(JSON.stringify(result, null, 2));

代码说明

  • collectAllNodes:递归遍历输入,收集所有节点并通过Map确保每个id唯一
  • buildHierarchy:
    • 先构建节点映射和父子关系映射,提升查找效率
    • buildNode递归转换节点结构,自动处理子节点嵌套
    • 筛选顶层节点生成最终层级结构
  • 自动处理info为空的情况,转换为null匹配目标输出格式

内容的提问来源于stack exchange,提问作者JimminyCricket

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:40:43