我想获取当前月份接下来 12 个月的预计 Balance
,如果该月的 Balance
为空,它将从最近的值中获取值Month
,Balance
大于 0。
void Main()
{
var firstDayMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
var months = Enumerable.Range(0, 12)
.Select(m => new
{
Month = firstDayMonth.AddMonths(m)
});
List<SomeDate> SomeDates = new List<SomeDate>()
{
new SomeDate { Id = 1, Month = firstDayMonth.AddMonths(0), Balance = 1m },
new SomeDate { Id = 2, Month = firstDayMonth.AddMonths(2), Balance = 1m },
new SomeDate { Id = 3, Month = firstDayMonth.AddMonths(1), Balance = 6m },
new SomeDate { Id = 4, Month = firstDayMonth.AddMonths(2), Balance = 5m },
new SomeDate { Id = 5, Month = firstDayMonth.AddMonths(3), Balance = 3m },
new SomeDate { Id = 6, Month = firstDayMonth.AddMonths(2), Balance = 2m },
new SomeDate { Id = 7, Month = firstDayMonth.AddMonths(3), Balance = 4m },
new SomeDate { Id = 8, Month = firstDayMonth.AddMonths(1), Balance = 2m },
new SomeDate { Id = 9, Month = firstDayMonth.AddMonths(3), Balance = 3m },
};
var groupedMonths = SomeDates
.GroupBy(c => c.Month)
.Select(g => new
{
Month = g.Key,
SumBalance = g.Sum(s => s.Balance)
});
var Projected12MonthsBalance = from m in months
join gm in groupedMonths on m.Month equals gm.Month into mm
from gm in mm.DefaultIfEmpty()
select new
{
Month = m.Month,
Balance = gm == null ? 0m : gm.SumBalance
};
Console.WriteLine(Projected12MonthsBalance);
}
// Define other methods and classes here
public class SomeDate
{
public int Id { get; set; }
public DateTime Month { get; set; }
public decimal Balance { get; set; }
}
到目前为止,这是我尝试过的。这将导致:
Month | Balance
7/1/2015 | 1
8/1/2015 | 8
9/1/2015 | 8
10/1/2015 | 10
11/1/2015 | 0
...
6/1/2016 | 0
是否有可能得到类似这样的结果:
Month | Balance
7/1/2015 | 1
8/1/2015 | 8
9/1/2015 | 8
10/1/2015 | 10
11/1/2015 | 10 <-- gets the value from the nearest month with Balance greater than 0
...
6/1/2016 | 10 <-- gets the value from the nearest month with Balance greater than 0
我似乎无法完成查询,所以我暂时设置为零。任何帮助将非常感激。谢谢!
最佳答案
恕我直言,使用 LINQ 似乎很容易。
首先,我修改了 months
以避免使用匿名类型(因为没有必要)。
var months =
Enumerable
.Range(0, 12)
.Select(m => firstDayMonth.AddMonths(m));
然后我创建了一个按月查找余额的图表:
var lookup =
SomeDates
.ToLookup(x => x.Month, x => x.Balance);
查找比分组依据或字典更好,因为您可以在键不存在的情况下请求查找的值并返回一个空列表。它减少了在检索值之前检查键是否存在的需要。
我将使用 .Aggregate(...)
构建最终列表,因此我需要为聚合函数创建初始的 accumulator
:
var accumulator =
months
.Take(1)
.Select(m => new { Month = m, Balance = lookup[m].Sum() })
.ToList();
这只是计算第一个月的余额并将其添加到列表中的结果。这是一个匿名类型的列表。
现在最后的查询很简单了:
var Projected12MonthsBalance =
months
.Skip(1)
.Aggregate(
accumulator,
(a, m) =>
{
var b = lookup[m].Sum();
b = b == 0 ? a.Last().Balance : b;
a.Add(new { Month = m, Balance = b });
return a;
});
此查询跳过第一个月,因为我们已经将它添加到累加器中。 lamdba 函数现在只计算每个月的余额,如果余额为零,则取下个月的余额。
这是我得到的结果:
关于c# - 如何用空月获得接下来的 12 个月,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31224242/