【问题标题】:Flatten nested objects with lodash用 lodash 展平嵌套对象
【发布时间】:2017-10-19 22:35:48
【问题描述】:

我正试图用 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 层嵌套,如示例中所示。

【问题讨论】:

    标签: javascript lodash


    【解决方案1】:

    您可以简单地使用 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' || !obj[key]) {
            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));
    

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

    【讨论】:

      【解决方案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);

      当然,这不一定非常漂亮或灵活(根据您对单层深度的假设)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-29
        • 1970-01-01
        • 2018-10-24
        • 2020-09-05
        • 2017-07-02
        • 2020-12-22
        • 2022-01-08
        • 1970-01-01
        相关资源
        最近更新 更多