如何从对象数组构造对象树(展开数组)

时间:2018-09-09 00:12:30

标签: javascript arrays object recursion

我目前有一个平面对象数组,我试图将其转换为嵌套的对象数组。无论数组的最终深度如何,我都希望在整个应用程序中重用此函数,因此我相信递归函数会更合适。

到目前为止,我的尝试一直是sort + reduce的结合,但没有成功。

如果能帮助我为我的应用程序编写一个简洁的功能,将不胜感激!

  

初始数组-对象的平面列表

const data = [
  { index: 0, parentKey: '-LLnMWy69vACjys0QIGH', type: 'options', name: 'OPTION_1', key: '-LLnOxg5hsDYR-PcfjBT' },
  { index: 1, parentKey: '-LLnMWy69vACjys0QIGH', type: 'options', name: 'OPTION_2', key: '-LLnP-O6TyHxIpPk9bCU' },
  { index: 0, parentKey: '-LLnLuLt6cn-vBpMWv-u', type: 'collections', name: 'COLLECTION_1', key: '-LLnMWy69vACjys0QIGH' },
  { index: 1, parentKey: '-LLnLuLt6cn-vBpMWv-u', type: 'collections', name: 'COLLECTION_2', key: '-LLnMYNyJmhSCPB-8lL1' },
  { index: 0, name: 'CONFIGURATOR_1', key: '-LLnLuLt6cn-vBpMWv-u' },
  { index: 1, name: 'CONFIGURATOR_2', key: '-LLnLtLs7PjXSAW0PWCQ' },
];
  

所需结果-嵌套的对象数组

const data = [
  {
    key: '-LLnLuLt6cn-vBpMWv-u',
    name: 'CONFIGURATOR_1',
    collections: [
      {
        key: '-LLnMWy69vACjys0QIGH',
        name: 'COLLECTION_1',
        options: [
          {
            key: '-LLnOxg5hsDYR-PcfjBT',
            name: 'OPTION_1',
          },
          {
            key: '-LLnP-O6TyHxIpPk9bCU',
            name: 'OPTION_2',
          },
        ],
      },
      {
        key: '-LLnMYNyJmhSCPB-8lL1',
        name: 'COLLECTION_2',
      },
    ],
  },
  { key: '-LLnLtLs7PjXSAW0PWCQ',
    name: 'CONFIGURATOR_2',
}]

2 个答案:

答案 0 :(得分:0)

对于此问题,通常,最简单的方法之一是使用映射M对所有对象进行索引。

然后,遍历地图M,如果当前键控元素具有父级,则将其添加到地图M中的键控父级,然后将所有这些元素映射到数组A。由于javascript中的所有对象都是引用,因此树结构将自动重建。

最后一步是过滤掉A中所有具有父元素的元素。

const data = [
    { index: 0, parentKey: '-LLnMWy69vACjys0QIGH', type: 'options', name: 'OPTION_1', key: '-LLnOxg5hsDYR-PcfjBT' },
    { index: 1, parentKey: '-LLnMWy69vACjys0QIGH', type: 'options', name: 'OPTION_2', key: '-LLnP-O6TyHxIpPk9bCU' },
    { index: 0, parentKey: '-LLnLuLt6cn-vBpMWv-u', type: 'collections', name: 'COLLECTION_1', key: '-LLnMWy69vACjys0QIGH' },
    { index: 1, parentKey: '-LLnLuLt6cn-vBpMWv-u', type: 'collections', name: 'COLLECTION_2', key: '-LLnMYNyJmhSCPB-8lL1' },
    { index: 0, name: 'CONFIGURATOR_1', key: '-LLnLuLt6cn-vBpMWv-u' },
    { index: 1, name: 'CONFIGURATOR_2', key: '-LLnLtLs7PjXSAW0PWCQ' },
];

const M = data.reduce(function (result, el) {
    result[el.key] = el
    return result;
}, {});
const A = Object.keys(M).map(key => {
    const el = M[key]
    if (M[el.parentKey]) {
        if (!M[el.parentKey].collections) {
            M[el.parentKey].collections = []
        }
        M[el.parentKey].collections.push(el)
    }
    return el
}).filter(el => {
    return !el.parentKey
})

console.log(JSON.stringify(A, null, '\t'))

答案 1 :(得分:0)

我使用以下功能发现了我的问题。我敢肯定还有其他更有效的方法,但这是我发现的最干净的选择!

const objectNest = (array, parentKey) => {
  const output = [];
  array.forEach((object) => {
    if (object.parentKey === parentKey) {
      const children = objectNest(array, object.key);
      if (children.length) { object[children[0].type] = children; }
      const { index, parentKey, ...content } = object;
      output.push(content);
    }
  });
  return output;
};