【问题标题】:Simple way to turn array of objects into object with grouped keys as arrays将对象数组转换为具有分组键作为数组的对象的简单方法
【发布时间】:2019-01-03 03:16:44
【问题描述】:

我正在寻找一种简单的方法来执行以下操作。我试过用lodash.reduce 来做这件事,但它很笨重,有没有更简单的方法。

发件人:

[{a: 'meow'}, {a: 'woof'}]

收件人:

{a: ['meow', 'woof']}

【问题讨论】:

  • 愿意分享努力吗?拥有您代表的用户应该知道它的重要性

标签: javascript typescript lodash


【解决方案1】:

你可以用纯 JS 做到这一点,不需要 loadash。

在您的输入数组上调用数组的reduce 方法,并将该数组归约为一个对象,循环遍历您内部对象的键:

const input = [{a: 'meow'}, {a: 'woof'}, {b: 'hi'}, {a: 'dog', c: 'bye'}, {}];

console.log(input.reduce((acc, val) => {
  Object.keys(val).forEach(key => {
    if(!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(val[key]);
  });
  return acc;
}, {}));

【讨论】:

  • 我在输入集中添加了更多对象,只是为了展示这个在广义集上的工作。 +1。如果您不喜欢此更改,您可以回滚。在那种情况下我很抱歉
【解决方案2】:

您可以使用lodash#assignWith 将所有属性各自的值分配到一个对象中,并使用自定义函数来确定您希望如何构造该对象。

const result = _.assignWith({}, ...data, (v = [], s) => v.concat(s));

注意:为了确保我们不会改变 data 数组中的任何对象,我传递了一个空对象作为第一个参数来充当目标对象。

const data = [
  { a: 'meow' },
  { a: 'woof', k: 'hey' },
  { k: 'yo', d: 'hehe' },
  { d: 'wazup', q: 'ohoho' }
];

const result = _.assignWith({}, ...data, (v = [], s) => v.concat(s));

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

【讨论】:

  • 另外,_.mergeWith 也可以用同样的方式
  • 由于 OP 的情况不涉及递归赋值,所以我只是选择使用lodash#assignWith
【解决方案3】:

我在使用 typescript 和 lodash.reduce 时遇到了一些问题,这很有效。

export function getFuncsObject(funcs): Record<Funcs, Case[]> {
  let f = { ...funcs };
  f = lodash.mapValues(f, () => []);
  return f;
}

export function mockMerge(funcs, mocks: Record<Funcs, Case | null>[]): Record<Funcs, Case[]> {
  const f = getFuncsObject(funcs);
  lodash.each(mocks, (v, k) => {
    f[k].push(v);
  });
  return f;
}

【讨论】:

    【解决方案4】:

    一种选择是使用如下两种缩减:

    const input = [{
      a: 'meow'
    }, {
      a: 'woof'
    }, {
      b: 'moo'
    }];
    
    const result = input
    .reduce((itemResult, item) => Object.keys(item)
    .reduce((keyResult, key) => ({
      ...keyResult,
      [key]: (keyResult[key] || []).concat(item[key])
    }), itemResult), {});
    
    console.log(result)

    不确定这与您当前的解决方案相比是否笨拙,但它相当简洁并且不需要外部库。

    【讨论】:

      【解决方案5】:

      不使用任何外部库或减少。

      const input = [ {a: 'meow'}, {a: 'woof'}, {b: 'hi'}, {a: 'dog', c: 'bye'}, {} ];
      let output = {};
      
      input.forEach((inputObj) => {
        for(let key in inputObj){
          if(!output[ key ]){
            output[ key ] = [];
          }
          output[ key ].push(inputObj[key])
        }
      });
      
      
      console.log(output);

      【讨论】:

        猜你喜欢
        • 2020-05-03
        • 2021-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 2022-11-17
        相关资源
        最近更新 更多