我有一个数据集(汽车):
Brand DateSold Amount Bought/Sold
Toyota 06/07/2015 18.5 Bought
BMW 01/01/2016 25.15 Sold
Mercedes 06/06/2016 20.75 Bought
我想按年份分组并返回金额的总和,即:
Year Amount
2015 -18.5
2016 4.4
并将其输出到列表框中。
我可以在没有购买/出售条件的情况下求和:
var AmountsByYear = cars.GroupBy(i => i.Date.Year)
.Select(g => new {
Year = g.Key,
Total = g.Sum(i => i.Amount)
}).ToList();
lstAmountsByYear.DataSource = AmountsByYear;
答案 0 :(得分:1)
由于您没有详细说明如何在数据结构中定义“购买/出售”字段,因此建议您使用一个枚举。例如,
public class Car
{
public string Brand;
public DateTime Date;
public double Amount;
public BusinessType BusinessType;
}
public enum BusinessType
{
Bought = -1,
Sold = 1
}
这将使您以最小的变化使用查询,以达到预期的结果。
var AmountsByYear = cars.GroupBy(i => i.Date.Year)
.Select(g => new {
Year = g.Key,
Total = g.Sum(i => i.Amount*(int)i.BusinessType)
}).ToList();
输入数据,
var cars = new List<Car>
{
new Car{Brand="Toyota", Date = new DateTime(2015,06,07),Amount=18.5,BusinessType=BusinessType.Bought},
new Car{Brand="BMW", Date = new DateTime(2016,01,01),Amount=25.15,BusinessType=BusinessType.Sold},
new Car{Brand="Mercedes", Date = new DateTime(2016,06,06),Amount=20.75,BusinessType=BusinessType.Bought},
};
输出
答案 1 :(得分:0)
考虑创建Car
的扩展方法,该方法将[Amount
,bought
/ sold
]的组合转换为Amount
的正值或负值:
public static decimal ToProperAmountValue(this Car car)
{
return car.IsCarBought ? -car.Amount : car.Amount;
}
// TODO: invent proper method name
此外,使用已经为您执行“选择”的正确overload of Enumerable.GroupBy:
var amountsByYear = cars.GroupBy(
// KeySelector: Group Cars into Groups of same year
car => car.Date.Year)
// ResultSelector: take the Key and the Cars with this Key to make a new object
(year, carsInThisYear => new
{
Year = year,
Total = carsInThisYear.Sum(car => car.ToProperAmountValue())
})
.ToList();