Any good groupBy way when converting values ​​using Lo-Dash 3.0?

Given an array of such objects:

var data = [ {key: 'a', val: '1'}, {key: 'a', val: '2'}, {key: 'b', val: '3'}, {key: 'c', val: '4'}, {key: 'c', val: '5'}, {key: 'c', val: '6'} ]; 

I would like to convert it to this:

 var desiredResults = { 'a': [1, 2], 'b': [3], 'c': [4, 5, 6] }; 

I found two ways to achieve this so far with lodash-fp , but I'm still wondering if there is a better way.

The first method is somewhat procedural:

 var out = _(data) .transform(function(out, item) { out[item.key] = out[item.key] || []; out[item.key].push(item.val); }, {}); 

The second way is the dot style that I was hoping to achieve:

 var out = _(data) .groupBy(_.property('key')) .mapValues(_.map(_.property('val'))) .value(); // Yes, I know that _.property is implied if I just pass a string 

However, this is more clutter than I would like: I need to iterate over the intermediate results in order to convert the grouped values, and I think it obscures what the code is trying to execute. I can’t convert first, though, since the conversion I want removes the keys!

Is there something like groupByTransforming(groupIteratee, transformIteratee) method?

+6
source share
1 answer

I don't know anything about LoDash (sorry), but I have a simple function that will do what you want, just use vanilla JS:

 /** * Maps an array of objects into a single object, * grouped by one property and supplying another. * @param {Array} input The array of objects containg data * @param {String} groupBy The name of the property to group the elements by * @param {String} groupProp The property to push into each array * @return {Object} The mapped object. */ function mapToObject(input, groupBy, groupProp) { var obj = {}; // Loop through the data input.forEach(function (data) { // If the output object doesn't contain the key, // make it as an empty array if (!obj[data[groupBy]]) { obj[data[groupBy]] = []; }; // Push the value into the obj[groupBy] array obj[data[groupBy]].push(data[groupProp]); }); return obj; } 

In your case, you will use it as follows:

mapToObject (data, 'key', 'val'), so it returns an object of data grouped by key and with values ​​of 'val'. Below is a snippet below:

 var data = [ {key: 'a', val: '1'}, {key: 'a', val: '2'}, {key: 'b', val: '3'}, {key: 'c', val: '4'}, {key: 'c', val: '5'}, {key: 'c', val: '6'} ]; /** * Maps an array of objects into a single object, * grouped by one property and supplying another. * @param {Array} input The array of objects containg data * @param {String} groupBy The name of the property to group the elements by * @param {String} groupProp The property to push into each array * @return {Object} The mapped object. */ function mapToObject(input, groupBy, groupProp) { var obj = {}; // Loop through the data input.forEach(function (data) { // If the output object doesn't contain the key, // make it as an empty array if (!obj[data[groupBy]]) { obj[data[groupBy]] = []; }; // Push the value into the obj[groupBy] array obj[data[groupBy]].push(data[groupProp]); }); return obj; } // Just to show example output: document.write(JSON.stringify(mapToObject(data, 'key', 'val'))); 
+2
source

Source: https://habr.com/ru/post/981782/


All Articles