在Javascript中将对象数组转换为嵌套对象

时间:2018-09-07 16:11:08

标签: javascript arrays object recursion ecmascript-6

我想使用递归函数将对象数组转换为嵌套对象。

目标是创建一个无论我的初始数组深度如何都可以工作的函数。您可以在下面看到具有预期结果的原始数据+尝试解决此问题的代码段。

  

对象的初始数组

configurator: [
  {
    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',
  }]
  

所需结果:嵌套对象

configurator: {
  '-LLnLuLt6cn-vBpMWv-u': {
    name: 'CONFIGURATOR_1',
    index: 0,
    collections: {
      '-LLnMWy69vACjys0QIGH': {
        name: 'COLLECTION_1',
        index: 0,
        options: {
          '-LLnOxg5hsDYR-PcfjBT': {
            name: 'OPTION_1',
            index: 0,
          },
          '-LLnP-O6TyHxIpPk9bCU': {
            name: 'OPTION_2',
            index: 1,
          },
        },
      },
      '-LLnMYNyJmhSCPB-8lL1': {
        name: 'COLLECTION_2',
        index: 1,
      },
    },
  },
  '-LLnLtLs7PjXSAW0PWCQ': {
    name: 'CONFIGURATOR_2',
    index: 1,
  },
}
  

我的尝试

这是到目前为止我尝试过的代码片段。它仅适用于数组的第一个深度。我相信这是要解决的挑战:如何动态地将对象添加/“推”到嵌套对象中?

希望有人可以提供帮助。干杯,朱利安。

const data = {
  configurator: [{
      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',
    }
  ]
};


const format = (object) => {
  const result = {};
  Object.keys(object).forEach((property) => {
    if (Array.isArray(object[property])) {
      object[property].forEach((test, index) => {
        const {
          key,
          ...content
        } = test;
        result[key] = {
          index,
          ...content
        };
        format(content);
      });
    }
  });
  return result;
};

const formated = format(data);
console.log('@FORMATED__', formated);

2 个答案:

答案 0 :(得分:0)

实际上,这必须递归完成。只需reduce将数组放入对象。对于每个对象,找到将数组作为值的键,然后将其应用于它们:

const format = array => 
    array.reduce((acc, obj, index) => {
        const {key, ...rest} = obj;
        Object.keys(rest)                                            // get the keys of the rest of the object
              .filter(key => Array.isArray(rest[key]))               // filter those that have arrays as values
              .forEach(key => rest[key] = format(rest[key]));        // for each one of them, format their array and assign them back to the rest object
        acc[key] = { ...rest, index };                               // create the new object and assign it to the accumulator
        return acc;
    }, {});

示例:

const format = array => 
    array.reduce((acc, obj, index) => {
        const {key, ...rest} = obj;
        Object.keys(rest)
              .filter(key => Array.isArray(rest[key]))
              .forEach(key => rest[key] = format(rest[key]));
        acc[key] = { ...rest, index };
        return acc;
    }, {});

const arr = [{"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"}];

console.log(format(arr));

注意:例如,如果某些数组可能不只包含您要跳过的对象,则只需将过滤条件更改为:

.filter(key => Array.isArray(rest[key]))

收件人:

.filter(key => Array.isArray(rest[key]) && rest[key].every(item => item && typeof item === "object"))

先检查数组是否仅包含对象,然后再对其应用format

答案 1 :(得分:0)

已编辑

UnloadedBehavior="Close"