用lodash压平嵌套对象

时间:2017-05-19 17:46:27

标签: javascript lodash

我正在试图用lodash做下面的事情。我有一个包含更多嵌套对象的对象数组,如下所示:

[{
    id: 123,
    name: 'John',
    summary1: {
        count: 3,
        sum: 10,
    },
    summary2: {
        count: 10,
        sum: 20
    },
},
...
]

我想将此数组的每个元素转换为以下内容:

[{
    id: 123,
    name: 'John',
    summary1_count: 3,
    summary1_sum: 10
    summary2_count: 10,
    summary2_sum: 20,
},
...
]

所以基本上我想要“扁平化”数组的每个元素,以便基于主键和子键确定对象键。我怎样才能使用lodash或普通JS来实现这个目标?

您可以假设示例中只有1级嵌套。

2 个答案:

答案 0 :(得分:3)

您只需使用npm包flat

import flat from 'flat';

const array = [
  {
    a: 'a',
    b: {
      bb: 'bb',
    },
    c: {
      cc1: 'cc1',
      cc: {
        ccc: 'ccc',
        ccd: 'ccd',
      },
    },
  },
  // ...
];

const flattenedArray = array.map(flat);

/*
  flattenedArray === [
    {
      a: 'a',
      b.bb: 'bb',
      c.cc1: 'cc1',
      c.cc.ccc: 'ccc',
      c.cc.ccd: 'ccd',
    },
    // ...
  ]
*/

如果你想自己实现它,这是flat的实现:

const flat = (obj, concatenator = '.') => (
  Object.keys(obj).reduce(
    (acc, key) => {
      if (typeof obj[key] !== 'object') {
        return {
          ...acc,
          [key]: obj[key],
        };
      }

      const flattenedChild = flat(obj[key], concatenator);

      return {
        ...acc,
        ...Object.keys(flattenedChild).reduce((childAcc, childKey) => ({ ...childAcc, [`${key}${concatenator}${childKey}`]: flattenedChild[childKey] }), {}),
      };
    },
    {},
  )
);

const flattenedArray = array.map(o => flat(o));

这些解决方案可以适用于任何深度。

答案 1 :(得分:2)

你可以在没有lodash(或其他库)的情况下通过迭代原始数组中每个项的键,检查它们的类型,并进一步迭代它们的内部键,构建新的键来保存正确的值。



const array = [{
  id: 123,
  name: 'John',
  summary1: {
    count: 3,
    sum: 10
  },
  summary2: {
    count: 10,
    sum: 20
  }
}];


let newArray = array.map(item => {
  let newObj = {};

  Object.keys(item).forEach(key => {
    if (typeof item[key] === 'object') {
      Object.keys(item[key]).forEach(innerKey => {
        newObj[`${key}_${innerKey}`] = item[key][innerKey];
      });
    } else {
      newObj[key] = item[key];
    }
  });

  return newObj;
});

console.log(newArray);




当然,这不一定非常漂亮或灵活(假设你有一个单一级别)。