首页 > 解决方案 > 合并对象数组而不覆盖

问题描述

我目前正在使用一些 JSON,它必须以树状层次结构构建。层次结构的深度变化很大,因此是未知的。

就像现在一样,我已经获得了一组对象。示例如下。

[
    {
      "name": "level1",
      "collapsed": true,
      "children": [
        {
          "name": "Level 1 item here",
          "id": 360082134191
        }
      ]
    },
    {
      "name": "level1",
      "collapsed": true,
      "children": [
        {
          "name": "level2",
          "collapsed": true,
          "children": [
            {
              "name": "Level 2 item here",
              "id": 360082134751
            }
          ]
        }
      ]
    },
    {
      "name": "level1",
      "collapsed": true,
      "children": [
        {
          "name": "Another level 1 item",
          "id": 360082262772
        }
      ]
    }
  ]

我想要实现的是这些对象被合并,而不覆盖或替换任何东西。下面列出的是我希望如何格式化数据的示例:

[
  {
    "name": "level1",
    "collapsed": true,
    "children": [
      {
        "name": "level2",
        "collapsed": true,
        "children": [
          {
            "name": "Level 2 item here",
            "id": 360082134751
          }
        ]
      },
      {
        "name": "Level 1 item here",
        "id": 360082134191
      },
      {
        "name": "Another level 1 item",
        "id": 360082262772
      }
    ]
  }
]

我将如何使用 JavaScript 实现这一点?没有库是首选,但可以使用 ES6。

编辑: 输出是一个数组很重要,因为没有子项的项目可以出现在根目录中。

标签: javascriptjsonecmascript-6treeview

解决方案


我假设您在处理数据方面需要一些帮助。可能有多种方法可以实现这一点,这就是我该怎么做。

// data => supplied data
const result = data.reduce ((acc, item) => {
  // if acc array already contains an object with same name,
  // as current element [item], merfe the children
  let existingItem;

  // Using a for loop here to create a reference to the
  // existing item, so it'd update this item when childrens
  // will be merged.
  for (let index = 0; index < acc.length; index ++) {
    if (acc[index].name === item.name) {
      existingItem = acc[index];
      break;
    }
  }
  // if existingItem exists, merge children of
  // existing item and current item.
  // else push it into the accumulator
  if (existingItem) {
    existingItem.children = existingItem.children.concat(item.children);
  } else {
    acc.push (item);
  }
  return acc;
}, []);

推荐阅读