Gruppieren Sie nach und summieren Sie mit Unterstrich/Lodash
-
21-12-2019 - |
Frage
Ich habe JSON wie folgt:
[
{
platformId: 1,
payout: 15,
numOfPeople: 4
},
{
platformId: 1,
payout: 12,
numOfPeople: 3
},
{
platformId: 2,
payout: 6,
numOfPeople: 5
},
{
platformId: 2,
payout: 10,
numOfPeople: 1
},
]
Und ich möchte es gruppieren nach platformId
mit Summe von payout
Und numOfPeople
.
D.h.Als Ergebnis möchte ich JSON wie folgt:
[
"1": {
payout: 27,
numOfPeople: 7
},
"2": {
payout: 16,
numOfPeople: 6
}
]
Ich habe versucht zu verwenden underscore.js
'S _.groupBy
Methode, und sie gruppiert gut, aber wie kann ich die SUMME der Objekteigenschaftenwerte erhalten, wie ich oben gezeigt habe?
Lösung
Sie können dies auch ohne Unterstrich tun:
var result = data.reduce(function(acc, x) {
var id = acc[x.platformId]
if (id) {
id.payout += x.payout
id.numOfPeople += x.numOfPeople
} else {
acc[x.platformId] = x
delete x.platformId
}
return acc
},{})
Aber warum sollten Sie ein Objekt mit Zifferntasten haben wollen?Sie könnten es wieder in eine Sammlung umwandeln:
var toCollection = function(obj) {
return Object.keys(obj)
.sort(function(x, y){return +x - +y})
.map(function(k){return obj[k]})
}
toCollection(result)
Beachten Sie, dass Objekte mutiert sind. Sie können sie daher zunächst klonen, wenn Sie die Originaldaten beibehalten möchten.
Andere Tipps
Hier ist ein Lodash Lösung für ein solches Problem.Es ähnelt Underscore, verfügt jedoch über einige erweiterte Funktionen.
const data = [{
platformId: 1,
payout: 15,
numOfPeople: 4
},
{
platformId: 1,
payout: 12,
numOfPeople: 3
},
{
platformId: 2,
payout: 6,
numOfPeople: 5
},
{
platformId: 2,
payout: 10,
numOfPeople: 1
},
];
const ans = _(data)
.groupBy('platformId')
.map((platform, id) => ({
platformId: id,
payout: _.sumBy(platform, 'payout'),
numOfPeople: _.sumBy(platform, 'numOfPeople')
}))
.value()
console.log(ans);
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
Ich habe versucht, dies auf funktionale Weise zu tun, und das Ergebnis war so
console.log(_.chain(data)
.groupBy("platformId")
.map(function(value, key) {
return [key, _.reduce(value, function(result, currentObject) {
return {
payout: result.payout + currentObject.payout,
numOfPeople: result.numOfPeople + currentObject.numOfPeople
}
}, {
payout: 0,
numOfPeople: 0
})];
})
.object()
.value());
Ganz im Sinne der Einzeiler von Lodash
_.map(_.groupBy(your_list, 'group_by'), (o,idx) => { return { id: idx, summed: _.sumBy(o,'sum_me') }})
Eine (meiner Meinung nach) schöne funktionale Möglichkeit, underscore.js zu verwenden:
var sum = function(t, n) { return t + n; };
_.mapObject(
_.groupBy(data, 'platformId'),
function(values, platformId) {
return {
payout: _.reduce(_.pluck(values, 'payout'), sum, 0),
numOfPeople: _.reduce(_.pluck(values, 'numOfPeople'), sum, 0)
};
}
);
//Input
[{
"platformId": 1,
"payout": 15,
"numOfPeople": 4
}, {
"platformId": 1,
"payout": 12,
"numOfPeople": 3
}, {
"platformId": 2,
"payout": 6,
"numOfPeople": 5
}, {
"platformId": 2,
"payout": 10,
"numOfPeople": 1
}]
//Output
{
"1": {
"payout": 43,
"numOfPeople": 13
},
"2": {
"payout": 43,
"numOfPeople": 13
}
}
// Code
output = _.reduce(input, function(acc, val, key) {
acc[val.platformId] = {
payout: _.sum(a, 'payout'),
numOfPeople: _.sum(a, 'numOfPeople')
};
return acc;
}, {});