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

如何为嵌套对象数组添加droppable/draggable属性并保留原结构

保留嵌套层级为对象数组添加属性的解决方案

问题描述

我有如下JavaScript嵌套对象数组:

const arr = [
  {
    "topicId": 1,
    "topicName": "Topic 1",
    "topicIcon": {
      "name": "Caret",
      "class": "lmnicon lmnicon-caret-right"
    },
    "topicContent": "T1 topic content",
    "children": [
      {
        "topicId": 4,
        "topicName": "Topic 4",
        "topicIcon": {
          "name": "Caret",
          "class": "lmnicon lmnicon-caret-right"
        },
        "topicContent": "T4 topic content"
      },
      {
        "topicId": 5,
        "topicName": "Topic 5",
        "topicIcon": {
          "name": "Caret",
          "class": "lmnicon lmnicon-caret-right"
        },
        "children": [
          {
            "topicId": 6,
            "topicName": "Topic 6",
            "topicIcon": {
              "name": "Caret",
              "class": "lmnicon lmnicon-caret-right"
            }
          },
          {
            "topicId": 7,
            "topicName": "Topic 7",
            "topicIcon": {
              "name": "Caret",
              "class": "lmnicon lmnicon-caret-right"
            }
          },
          {
            "topicId": 8,
            "topicName": "Topic 8",
            "topicIcon": {
              "name": "Caret",
              "class": "lmnicon lmnicon-caret-right"
            }
          },
        ]
      }
    ]
  },
  {
    "topicId": 2,
    "topicName": "Topic 2",
    "topicIcon": {
      "name": "Caret",
      "class": "lmnicon lmnicon-caret-right"
    },
    "topicContent": "T2 topic content",
    "children": [
      {
        "topicId": 9,
        "topicName": "Topic 9",
        "topicIcon": {
          "name": "Caret",
          "class": "lmnicon lmnicon-caret-right"
        }
      },
      {
        "topicId": 10,
        "topicName": "Topic 10",
        "topicIcon": {
          "name": "Caret",
          "class": "lmnicon lmnicon-caret-right"
        }
      }
    ]
  }
]

我需要为数组中所有对象及其任意层级的嵌套children对象添加droppable: true和draggable: true两个属性。目前尝试的代码虽然能添加属性,但会把原数组的层级结构扁平化,我需要保留原arr的层级结构,请问该如何实现?

之前尝试的代码:

const mapHeirarchy = list => list.flatMap(({ topicId, topicName, topicIcon,  children = [] }) => {
  const obj = {
    'topicId': topicId,
    'topicName': topicName,
    'topicIcon': topicIcon,
    'droppable': true, //add this
    'draggable': true  //add this
  }
  return [obj, ...mapHeirarchy(children)]
});
console.log(mapHeirarchy(arr))

解决方案

要保留原有的嵌套层级结构,需递归处理每个对象时保留其children属性,并对children数组递归调用处理函数,避免使用flatMap扁平化结构。

实现代码

const addDragDropProps = (list) => {
  return list.map(item => {
    // 解构原对象属性,children默认设为空数组
    const { children = [], ...rest } = item;
    // 返回新对象,添加目标属性并递归处理children
    return {
      ...rest,
      droppable: true,
      draggable: true,
      // 仅当存在子节点时,添加处理后的children属性
      ...(children.length > 0 && { children: addDragDropProps(children) })
    };
  });
};

// 调用函数处理原数组
const result = addDragDropProps(arr);
console.log(result);

代码说明

  • 使用map替代flatMap:map会生成与原数组长度一致的新数组,完全保留原层级结构。
  • 递归处理子节点:对每个对象的children数组递归调用处理函数,确保所有层级的子对象都添加目标属性。
  • 保留原属性:通过扩展运算符...rest保留原对象的所有未显式解构的属性(如topicContent),避免数据丢失。
  • 条件添加children:仅当原对象存在非空children数组时,才添加处理后的children属性,避免生成冗余的空数组。

兼容单个对象的扩展写法

如果需要同时支持单个对象和数组的处理,可以调整函数:

const addDragDropProps = (item) => {
  // 处理单个对象的情况
  if (!Array.isArray(item)) {
    const { children = [], ...rest } = item;
    return {
      ...rest,
      droppable: true,
      draggable: true,
      ...(children.length > 0 && { children: addDragDropProps(children) })
    };
  }
  // 处理数组的情况
  return item.map(addDragDropProps);
};

const result = addDragDropProps(arr);
console.log(result);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:28:13