可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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();