java 父子结构list转成拼接成自定义的数据

先有数据如下:
image.png

{
        "id": 1178,
        "name": "运动水壶",
        "description": null,
        "online": true,
        "parentId": 1169,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:34",
        "updateTime": "2021-03-31 11:41:34",
        "delFlag": "0"
    },
    {
        "id": 1993,
        "name": "运动相机",
        "description": null,
        "online": true,
        "parentId": 1983,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:48",
        "updateTime": "2021-03-31 11:41:48",
        "delFlag": "0"
    },
    {
        "id": 6023,
        "name": "运动跟踪器",
        "description": null,
        "online": true,
        "parentId": 6011,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:35",
        "updateTime": "2021-03-31 11:41:35",
        "delFlag": "0"
    },
    {
        "id": 6130,
        "name": "卫裤/运动裤",
        "description": null,
        "online": true,
        "parentId": 6122,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:37",
        "updateTime": "2021-03-31 11:41:37",
        "delFlag": "0"
    },
    {
        "id": 6224,
        "name": "户外/运动服",
        "description": null,
        "online": true,
        "parentId": 6214,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:35",
        "updateTime": "2021-03-31 11:41:35",
        "delFlag": "0"
    },
    {
        "id": 6260,
        "name": "运动鞋",
        "description": null,
        "online": true,
        "parentId": 6252,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:37",
        "updateTime": "2021-03-31 11:41:37",
        "delFlag": "0"
    },
    {
        "id": 6834,
        "name": "休闲运动包",
        "description": null,
        "online": true,
        "parentId": 6832,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:43",
        "updateTime": "2021-03-31 11:41:43",
        "delFlag": "0"
    },
    {
        "id": 6932,
        "name": "运动户外",
        "description": null,
        "online": true,
        "parentId": 0,
        "level": 0,
        "sort": null,
        "createTime": "2021-03-31 11:41:13",
        "updateTime": "2021-03-31 11:41:13",
        "delFlag": "0"
    },
    {
        "id": 7036,
        "name": "运动地胶",
        "description": null,
        "online": true,
        "parentId": 6933,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:50",
        "updateTime": "2021-03-31 11:41:50",
        "delFlag": "0"
    },
    {
        "id": 7057,
        "name": "高尔夫运动裤",
        "description": null,
        "online": true,
        "parentId": 6933,
        "level": 2,
        "sort": null,
        "createTime": "2021-03-31 11:41:50",
        "updateTime": "2021-03-31 11:41:50",
        "delFlag": "0"
    },
    {
        "id": 1169,
        "name": "水具酒具",
        "description": null,
        "online": true,
        "parentId": 1142,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:16",
        "updateTime": "2021-03-31 11:41:16",
        "delFlag": "0"
    },
    {
        "id": 1983,
        "name": "摄影摄像",
        "description": null,
        "online": true,
        "parentId": 1972,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:18",
        "updateTime": "2021-03-31 11:41:18",
        "delFlag": "0"
    },
    {
        "id": 6011,
        "name": "智能设备",
        "description": null,
        "online": true,
        "parentId": 1972,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:18",
        "updateTime": "2021-03-31 11:41:18",
        "delFlag": "0"
    },
    {
        "id": 6122,
        "name": "男装",
        "description": null,
        "online": true,
        "parentId": 6033,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:19",
        "updateTime": "2021-03-31 11:41:19",
        "delFlag": "0"
    },
    {
        "id": 6214,
        "name": "童装",
        "description": null,
        "online": true,
        "parentId": 6153,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:18",
        "updateTime": "2021-03-31 11:41:18",
        "delFlag": "0"
    },
    {
        "id": 6252,
        "name": "童鞋",
        "description": null,
        "online": true,
        "parentId": 6153,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:19",
        "updateTime": "2021-03-31 11:41:19",
        "delFlag": "0"
    },
    {
        "id": 6832,
        "name": "功能箱包",
        "description": null,
        "online": true,
        "parentId": 6831,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:20",
        "updateTime": "2021-03-31 11:41:20",
        "delFlag": "0"
    },
    {
        "id": 6933,
        "name": "体育用品",
        "description": null,
        "online": true,
        "parentId": 6932,
        "level": 1,
        "sort": null,
        "createTime": "2021-03-31 11:41:21",
        "updateTime": "2021-03-31 11:41:21",
        "delFlag": "0"
    },
    {
        "id": 1142,
        "name": "厨具",
        "description": null,
        "online": true,
        "parentId": 0,
        "level": 0,
        "sort": null,
        "createTime": "2021-03-31 11:41:13",
        "updateTime": "2021-03-31 11:41:13",
        "delFlag": "0"
    },
    {
        "id": 1972,
        "name": "数码",
        "description": null,
        "online": true,
        "parentId": 0,
        "level": 0,
        "sort": null,
        "createTime": "2021-03-31 11:41:13",
        "updateTime": "2021-03-31 11:41:13",
        "delFlag": "0"
    },
    {
        "id": 6033,
        "name": "服饰内衣",
        "description": null,
        "online": true,
        "parentId": 0,
        "level": 0,
        "sort": null,
        "createTime": "2021-03-31 11:41:13",
        "updateTime": "2021-03-31 11:41:13",
        "delFlag": "0"
    },
    {
        "id": 6153,
        "name": "母婴",
        "description": null,
        "online": true,
        "parentId": 0,
        "level": 0,
        "sort": null,
        "createTime": "2021-03-31 11:41:13",
        "updateTime": "2021-03-31 11:41:13",
        "delFlag": "0"
    },
    {
        "id": 6831,
        "name": "箱包皮具",
        "description": null,
        "online": true,
        "parentId": 0,
        "level": 0,
        "sort": null,
        "createTime": "2021-03-31 11:41:13",
        "updateTime": "2021-03-31 11:41:13",
        "delFlag": "0"
    }

需要转换成如下结构:
fullName: 父节点/子节点/子节点

{
    "id": "7036",
    "first": {
        "id": "6932",
        "name": "运动户外"
    },
    "second": {
        "id": "6933",
        "name": "体育用品"
    },
    "third": {
        "id": "7036",
        "name": "运动地胶"
    },
    "level": 3,
    "fullName": "运动户外/体育用品/运动地胶"
},
....
以下相同结构省略

请各位大神提供下实现方法跟思路,后端使用mybatis-plus

阅读 2.1k
2 个回答

假设有A/B/C , A/B/D , A/B , A/D四种排列,那是否需要舍弃A/B这种情况?

如果按照不需要舍弃来做,那就把所有数据存到map里,id为key,对应的数据为value。然后你就遍历每一个数据,根据parentId从map中找父菜单,父菜单的父菜单。这样就把父子结构找出来了。

如果按照需要舍弃来做,那大体还是上边的逻辑,只是要分三次遍历map,先遍历level=3的,然后level=2的,然后等于1的,并用另一个map记录被查找过的level=2和level=3的数据。这样你在遍历的level=2和1的时候,结合两个map就知道需不需要舍弃了。

懒得写 Java,要定义一堆类型还要做 JSON 转换。直接用 JavaScript 回答的,仅供参考

先拿当前数据列表生成一个字典,方便找父节点

const dict = Object.fromEntries(nodes.map(it => [it.id, it]));

然后遍历所有节点,把完整的路径找出来。

找某个节点的完整路径是一个递归过程,因为需要递归去找父节点:

function getPath(node) {
    const parent = dict[node.parentId];
    if (!parent) { return [node]; }
    return [...getPath(parent), node];
}

接下来是遍历:

const fullNodes = nodes.map(it => getPath(it));

得到原来每个节点对应的完整路径(数组),这每一个数据要处理成你想要的数据就相应容易了。唯一的疑问是 7034 这个 id 不知道是哪来的,先当你把 7036 写错了

const result = fullNodes.map(nodes => {
    const leaf = nodes[nodes.length - 1];
    return {
        id: leaf.id,
        level: nodes.length,
        fullName: nodes.map(it => it.name).join("/"),
        ...Object.fromEntries(nodes.map(({ id, name }, i) => [en[i], { id, name }]))
    };
});

这个结果包含了所有非叶节点的转换结果,如果不需要,在有规律的情况下可以按 level 值来过来(只留 level 值 为 3 的),无规律的情况下需要给叶节点打个标记,过滤掉就行。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题