Reputation: 129
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
Upvotes: 0
Views: 114
Reputation: 21825
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.
Upvotes: 1
Reputation: 1800
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"]
};
Upvotes: 1