I am working with highChart to create a column chart. Any how I reached to creating following arrayofObj via municating with database.
Now, I require to transform following source
array of object to below output.
var source = [
{data: 258, name: '2014'}
{data: 18, name: '2016'}
{data: 516, name: '2014'}
{data: 0, name: '2014'}
{data: 354, name: '2014'}
{data: 18, name: '2016'}
]`
Convert this array of object to
Output
[{
name: '2014',
data: [258, 516, 354]
}, {
name: '2016',
data: [18, 0, 18]
}]
Basically, I want my array to group by name (year) and data should be in array
Here is the solutions which i have applied.
var source = [];
_.each(source, function(singlerec) {
source.push({
name: singlerec.name,
data: singlerec.data // Here It only assign single record
});
});
I am working with highChart to create a column chart. Any how I reached to creating following arrayofObj via municating with database.
Now, I require to transform following source
array of object to below output.
var source = [
{data: 258, name: '2014'}
{data: 18, name: '2016'}
{data: 516, name: '2014'}
{data: 0, name: '2014'}
{data: 354, name: '2014'}
{data: 18, name: '2016'}
]`
Convert this array of object to
Output
[{
name: '2014',
data: [258, 516, 354]
}, {
name: '2016',
data: [18, 0, 18]
}]
Basically, I want my array to group by name (year) and data should be in array
Here is the solutions which i have applied.
var source = [];
_.each(source, function(singlerec) {
source.push({
name: singlerec.name,
data: singlerec.data // Here It only assign single record
});
});
Share
Improve this question
edited Jul 20, 2016 at 16:09
Denish
asked Jul 20, 2016 at 16:03
DenishDenish
2,8102 gold badges25 silver badges33 bronze badges
5
- @T.J.Crowder Thanks, Of course I have tried first, But you are right, I have added my progress in question. – Denish Commented Jul 20, 2016 at 16:11
-
Add what's wrong with the output of your solution. Also, with respect, your solution looks like it doesn't make any attempt at all to group things by
name
. Which is very much like asking someone else to add the grouping-by-name for you. – T.J. Crowder Commented Jul 20, 2016 at 16:12 - Also, search is your friend. :-) stackoverflow./questions/36069213/…, stackoverflow./questions/14592799/…, stackoverflow./questions/38079037/… – T.J. Crowder Commented Jul 20, 2016 at 16:13
- Possible duplicate of Lodash create collection from duplicate object keys – castletheperson Commented Jul 20, 2016 at 16:21
- @T.J.Crowder Lodash is so succinct, that the solution is usually all or nothing. I don't feel that seeing the OP's attempt improves the question, just as long as they actually made a real attempt. Functional programming can be difficult to grasp, especially when people try to blend it with imperative programming. – castletheperson Commented Jul 20, 2016 at 17:33
3 Answers
Reset to default 5In Lodash, I always use _.groupBy
and then _.map
to the output format.
var source = [{"data":258,"name":"2014"},{"data":18,"name":"2016"},{"data":516,"name":"2014"},{"data":0,"name":"2014"},{"data":354,"name":"2014"},{"data":18,"name":"2016"}];
var output = _(source)
.groupBy('name')
.map(function(v, k) { return { name: k, data: _.map(v, 'data') } })
.value();
console.log(output);
<script src="https://cdn.jsdelivr/lodash/4.13.1/lodash.min.js"></script>
I use a pure javascript function:
const pick = (obj, paths) => ({...paths.reduce((a, k) => ({...a, [k]: obj[k]}), {})})
function groupByAndConcat(data, groupBy, sums) {
return data.reduce((results, r) => {
const e = results.find((x) => groupBy.every((g) => x[g] === r[g]));
if (e) {
sums.forEach((k) => e[k] = [].concat(e[k], r[k]));
} else {
results.push(pick(r, groupBy.concat(sums)));
}
return results;
}, []);
}
So given your sample source:
const source = [
{data: 258, name: '2014'},
{data: 18, name: '2016'},
{data: 516, name: '2014'},
{data: 0, name: '2014'},
{data: 354, name: '2014'},
{data: 18, name: '2016'},
];
console.log(groupByAndConcat(source, ["name"], ["data"]))
outputs:
[{ name: "2014", data: Array [258, 516, 0, 354] }, { name: "2016", data: Array [18, 18] }]
It is also possible to group by or do operations on several props:
groupByAndConcat(source, ["name","month"], ["data","data2"])
there's a way to iterate array once with reduce
and even without lodash.
source.reduce((p, n) => {
(p[n.name] || (p[n.name] = [])).push(n.data);
return p
}, {})