using lodash .groupBy. how to add your own keys for grouped output?

匿名 (未验证) 提交于 2019-12-03 02:48:02

问题:

I have this sample data returned from an API.

I'm using Lodash's _.groupBy to convert the data into an object I can use better. The raw data returned is this:

[     {         "name": "jim",         "color": "blue",         "age": "22"     },     {         "name": "Sam",         "color": "blue",         "age": "33"     },     {         "name": "eddie",         "color": "green",         "age": "77"     } ]

I want the _.groupBy function to return an object that looks like this:

[     {         color: "blue",         users: [             {                 "name": "jim",                 "color": "blue",                 "age": "22"             },             {                 "name": "Sam",                 "color": "blue",                 "age": "33"             }         ]     },     {         color: "green",         users: [             {                 "name": "eddie",                 "color": "green",                 "age": "77"             }         ]     } ]

Currently I'm using

_.groupBy(a, function(b) { return b.color})

which is returning this.

{blue: [{..}], green: [{...}]}

the groupings are correct, but I'd really like to add the keys I want (color, users). is this possible using _.groupBy? or some other LoDash utility?

回答1:

You can do it like this

var result = _.chain(data)     .groupBy("color")     .pairs()     .map(function(currentItem) {         return _.object(_.zip(["color", "users"], currentItem));     })     .value(); console.log(result);

Online Demo

Note: Lodash 4.0 onwards, the .pairs function has been renamed to _.toPairs()



回答2:

Isn't it this simple?

var result = _(data)             .groupBy(x => x.color)             .map((value, key) => ({color: key, users: value}))             .value();


回答3:

another way

_.chain(data)     .groupBy('color')     .map((users, color) => ({ users, color }))     .value();


回答4:

Thanks @thefourtheye, your code greatly helped. I created a generic function from your solution using the version 4.5.0 of Lodash.

function groupBy(dataToGroupOn, fieldNameToGroupOn, fieldNameForGroupName, fieldNameForChildren) {             var result = _.chain(dataToGroupOn)              .groupBy(fieldNameToGroupOn)              .toPairs()              .map(function (currentItem) {                  return _.zipObject([fieldNameForGroupName, fieldNameForChildren], currentItem);              })              .value();             return result;         }

To use it:

var result = groupBy(data, 'color', 'colorId', 'users');

Here is the updated fiddler;

https://jsfiddle.net/sc2L9dby/



回答5:

I would suggest a different approach, using my own library you could do this in a few lines:

var groupMe = sequence(   groupBy(pluck('color')),   forOwn(function(acc, k, v) {     acc.push({colors: k, users: v});     return acc;   },[]) );  var result = groupMe(collection);

This would a be a bit difficult with lodash or Underscore because the arguments are in the opposite order order, so you'd have to use _.partial a lot.



回答6:

Here is an updated version using lodash 4 and ES6

const result = _.chain(data)     .groupBy("color")     .toPairs()     .map(pair => _.zipObject(['color', 'users'], pair))     .value();


回答7:

Highest voted answer uses Lodash _.chain function which is considered a bad practice now "Why using _.chain is a mistake."

Here is a fewliner that approaches the problem from functional programming perspective:

import tap from "lodash/fp/tap"; import flow from "lodash/fp/flow"; import groupBy from "lodash/fp/groupBy";  const map = require('lodash/fp/map').convert({ 'cap': false });  const result = flow(       groupBy('color'),       map((users, color) => ({color, users})),       tap(console.log)     )(input)

Where input is an array that you want to convert.



回答8:

Example groupBy and sum of a column using Lodash 4.17.4

   var data = [{                 "name": "jim",                 "color": "blue",                 "amount": 22                 }, {                 "name": "Sam",                 "color": "blue",                 "amount": 33                 }, {                "name": "eddie",                "color": "green",                "amount": 77               }];        var result = _(data)                    .groupBy(x => x.color)                    .map((value, key) =>                     ({color: key,                     totalamount: _.sumBy(value,'amount'),                     users: value})).value();                      console.log(result);


回答9:

I wrote a function that uses lodash and returns a grouped data.

let _ = require('lodash');  let values = [     { contract_id: "123", id_counterparty: "11" } ,      { contract_id: "124", id_counterparty: "12" } ,      { contract_id: "127", id_counterparty: "11" } ,      { contract_id: "129", id_counterparty: "14" } ,  ];  let res = _groupObjectsBy( 'id_counterparty', values, 'groupName', 'values' );  console.log( res );   function _groupObjectsBy( propName, objectsArray, outputGroupName, outputValuesName ) {     let result = _( objectsArray )         .groupBy( obj => obj[ propName ] )         .map( (values, key) => {             let obj = {};             obj[ 'groupedBy' ] = propName;             obj[ outputGroupName ] = key;             obj[ outputValuesName ] = values;             return obj;         })         .value();         return result; }

Result:

[ { groupedBy: 'id_counterparty',  groupName: '11', values: [ [Object], [Object] ] }, { groupedBy: 'id_counterparty', groupName: '12', values: [ [Object] ] }, { groupedBy: 'id_counterparty', groupName: '14', values: [ [Object] ] } ]


回答10:

In 2017 do so

_.chain(data)   .groupBy("color")   .toPairs()   .map(item => _.zipObject(["color", "users"], item))   .value();


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!