最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - linqjs group by with a sum - Stack Overflow

programmeradmin6浏览0评论

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 badges
Add a ment  | 

5 Answers 5

Reset to default 8

You 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?

发布评论

评论列表(0)

  1. 暂无评论