0

I have the following class:

class Item
{
    public decimal TransactionValue { get; set; }
    public string TransactionType { get; set; }
}

And I have this list:

        var items = new List<Item>
        {
            new Item
            {
                TransactionValue = 10,
                TransactionType = "Income"
            },
            new Item
            {
                TransactionValue = 10,
                TransactionType = "Income"
            },
            new Item
            {
                TransactionValue = -5,
                TransactionType = "Outgoing"
            },
            new Item
            {
                TransactionValue = -20,
                TransactionType = "Outgoing"
            }
        };

And I am trying to get the sums based on ValueType, I have tried the below but it is adding everything and giving me one total which is -5, what I want is totals for each transaction type so I want to get a new class which is Totals class below and with this data: TotalIncoming : 20 and TotalOutgoing : - 25.

        var r = items.Sum(x => x.TransactionValue);

class Totals
{
    public decimal TotalIncoming { get; set; }
    public decimal TotalOutgoing { get; set; }
}

Thanks

NHead
  • 129
  • 4
  • `var query = item.GroupBy(item=> item.TransactionType).Select(grp=> new { Key = grp.Key, Total = grp.Sum(r=> r.TransactionValue)});` – Habib Jan 22 '15 at 20:51
  • See: http://stackoverflow.com/questions/7325278/group-by-in-linq?rq=1, Related if not duplicate – Habib Jan 22 '15 at 20:52

2 Answers2

1

I'm sure there is a probably a clever way to do this in one line using Linq, but everything I could come up with was quite ugly so I went with something a bit more readable.

var results = items.GroupBy(x => x.TransactionType)
    .ToDictionary(x => x.Key, x => x.Sum(y => y.TransactionValue));

var totals = new Totals
{
    TotalIncoming = results["Income"],
    TotalOutgoing = results["Outgoing"]
};
Bradford Dillon
  • 1,750
  • 13
  • 24
1

You can achieve your desired result with following query:-

Totals result = new Totals
     {
        TotalIncoming = items.Where(x => x.TransactionType == "Income")
                             .Sum(x => x.TransactionValue),
        TotalOutgoing = items.Where(x => x.TransactionType == "Outgoing")
                             .Sum(x => x.TransactionValue)
     };

But, as you can see with your Type Totals, we need to hard-code the TransactionType and we have no clue from the result that this Sum belongs to which type apart from the naming convention used.

I will create the below type instead:-

class ItemTotals
{
   public string ItemType { get; set; }
   public decimal Total { get; set; }
}

Here we will have the TransactionType along with its corresponding Total in the result, we can simply group by TransactionType & calculate the sum, here is the query for same:-

List<ItemTotals> query = items.GroupBy(x => x.TransactionType)
                                          .Select(x => new ItemTotals
                                          {
                                              ItemType = x.Key,
                                              Total = x.Sum(z => z.TransactionValue)
                                          }).ToList();

Here is the Complete Working Fiddle, you can choose from both.

Rahul Singh
  • 21,585
  • 6
  • 41
  • 56