This might seems like an easy question but I'm struggling with the linqjs syntax.
Given the following basic JSON:
{
"DateEvent": "2013-04-23 14:00:00Z",
"DateRecord": "2013-04-23 14:00:00Z",
"Amount": -9500,
"Type": {
"Description": "Capital"
},
"Currency": {
"ID": "USD"
}
}
Using linqjs how can I return the total for each currency?
Enumerable.From(data)
.GroupBy("{ currency: $.Currency.ID }", null, function (key, g) {
var result = {
currency: key.currency,
total: g.Sum($.Amount)
}
});
The code above doesn't work.
This might seems like an easy question but I'm struggling with the linqjs syntax.
Given the following basic JSON:
{
"DateEvent": "2013-04-23 14:00:00Z",
"DateRecord": "2013-04-23 14:00:00Z",
"Amount": -9500,
"Type": {
"Description": "Capital"
},
"Currency": {
"ID": "USD"
}
}
Using linqjs how can I return the total for each currency?
Enumerable.From(data)
.GroupBy("{ currency: $.Currency.ID }", null, function (key, g) {
var result = {
currency: key.currency,
total: g.Sum($.Amount)
}
});
The code above doesn't work.
Share Improve this question edited Apr 18, 2023 at 12:18 KyleMit♦ 30k72 gold badges506 silver badges698 bronze badges asked Jul 24, 2013 at 1:59 paligappaligap 9422 gold badges13 silver badges28 bronze badges5 Answers
Reset to default 8You almost had it. Your key selector in your GroupBy and Sum is incorrect. Also the key selector needs to be a string. Try the following:
var result = Enumerable.from(data).groupBy("$.Currency.ID", null,
function (key, g) {
var result = {
currency: key,
total: g.sum("$.Amount")
}
return result;
}).ToArray();
I am the author of the open-source project http://www.jinqJs.
You could easily do it by executing:
new jinqJs().from(data).groupBy('Currency').sum('Amount').select();
Just to expand further on this question.
The following syntax will group the data by an additional field:
var result = Enumerable.from(data)
.groupBy("{ currency: $.Currency.ID, type: $.Type.Description }", null,
function (key, g) {
var result = {
currency: key.currency,
type: key.type,
total: g.Sum("$.Amount")
}
return result;
}, function (x) { return x.currency + ':' + x.type }).ToArray();
Assuming you have an array of objects that looks like that, you can write your query like this:
var query = Enumerable.from(data)
.groupBy(
"{ Currency: $.Currency.ID, Type: $.Type.Description }",
"$.Amount",
"{ Currency: $.Currency, Type: $.Type, Total: $$.Sum() }"
)
.ToArray();
Personally I find using the lambda string syntax more succinct and preferable. Mixing lambdas and functions leads to messier code IMHO.
Update with Native JS
With widespread support for JS operations in nearly any browser and the proliferation of build tools to pile down when necessary, unless you're already importing linqjs, I'd remend going with a native JS approach.
const grouped = data.reduce((acc, el) => {
const key = el.Currency.ID
const prev = acc[key] ?? 0
acc[key] = prev + el.Amount;
return acc;
}, {})
Demo in Stack Snippets
const data = [
{
"Amount": 5,
"Currency": { "ID": "USD" }
},
{
"Amount": 10,
"Currency": { "ID": "USD" }
},
{
"Amount": 20,
"Currency": { "ID": "CAN" }
}
]
const grouped = data.reduce((acc, el) => {
const key = el.Currency.ID
const prev = acc[key] ?? 0
acc[key] = prev + el.Amount;
return acc;
}, {})
console.log(grouped)
// {
// "USD": 15,
// "CAN": 20
// }
See Also: How to group by and sum an array of objects?