简体   繁体   English

将对象数组转换为具有分组键作为数组的对象的简单方法

[英]Simple way to turn array of objects into object with grouped keys as arrays

I am looking for a simple way to do the following.我正在寻找一种简单的方法来执行以下操作。 I have tried to do this with lodash.reduce and it is clunky, is there an easier way.我试图用lodash.reduce来做到这lodash.reduce ,但它很笨重,有没有更简单的方法。

From:从:

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

To:到:

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

You can do that with pure JS, no need of loadash.你可以用纯 JS 做到这一点,不需要 loadash。

Call the reduce method of arrays on your input array, and reduce the array to an object, looping over the keys of your inner objs:在输入数组上调用数组的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; }, {}));

You can use lodash#assignWith to assign all properties their respective values into one object, together with a customizer function to determine how you want to structure the object.您可以使用lodash#assignWith将所有属性各自的值分配到一个对象中,并使用自定义函数来确定您希望如何构建对象。

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

Note: To make sure that we don't mutate any of the objects in the data array, I passed an empty object as the first parameter to act as the destination object.注意:为了确保我们不会改变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>

I had some issues with typescript and lodash.reduce, this worked.我在打字稿和 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;
}

One option would be to use two reductions as follows:一种选择是使用以下两种减少:

 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)

Not sure if this is clunky compared to your current solution, but it's fairly concise and does not require an external library.不确定这与您当前的解决方案相比是否笨重,但它相当简洁并且不需要外部库。

Without using any external libraries or reduce.不使用任何外部库或减少。

 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);

I am looking for a simple way to do the following.我正在寻找一种简单的方法来执行以下操作。 I have tried to do this with lodash.reduce and it is clunky, is there an easier way.我试图用lodash.reduce做到这lodash.reduce ,它很笨重,有没有更简单的方法。

From:从:

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

To:至:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM