假设类数据定义为 {DateTime TransactionDate,int ItemCount} 。 我得到一个包含分散的TransactionDates和ItemCounts的原始IEnumerable,我需要编写一个方法来返回一个集合,其中包含原始集合中最小和最大天数之间的所有日期。
例如,如果我得到:
12/5/2009 15.00
12/7/2009 10.00
12/10/2009 75.00
我需要生成这样的东西:
12/5/2009 15.00
12/6/2009 0.00
12/7/2009 10.00
12/8/2009 0.00
12/9/2009 0.00
12/10/2009 75.00
让你用c#3.0给我一个优雅的方法吗?
我列出了最短和最长日期之间的所有日期。所以我假设我所要做的就是“预约”交集集合(allDates-existingDates)并为每个集合插入一个新元素。我对吗?
由于
答案 0 :(得分:2)
这是一个应该完成工作的扩展方法。它纯粹基于迭代器(IEnumerable<Data>
),所以对我来说这似乎是一个很好的方法。
public static IEnumerable<Data> FillIn(this IEnumerable<Data> original)
{
Data lastItem = null;
foreach (var item in original)
{
if (lastItem != null)
{
var fakeItem = new DateTime(lastItem.TransactionDate.Year,
lastItem.TransactionDate.Month, lastItem.TransactionDate.Day)
.AddDays(1);
while (fakeItem.TransactionDate != item.TransactionDate)
{
yield return fakeItem;
fakeItem.TransactionDate = fakeItem.TransactionDate.AddDays(1);
}
}
lastItem = item;
yield return item;
}
}
Data
简单定义为:
class Data
{
public DateTime TransactionDate;
public int ItemCount;
}
答案 1 :(得分:1)
假设你的收藏是一本字典(日期是唯一的,可以用作关键字),你可以做一些喜欢这样的事情:
-1。确定源集合中的第一个和最后一个日期(如果集合是sortedDictionary,则包含第一个和最后一个元素。)
-2。创建一个IEnumerator,它可以迭代给定开始日期和结束日期之间的所有日期。
-3。使用foreach结构,使用Enumerator以及您收集的获得的开始和结束日期。在每个步骤中,检查当前日期是否是源列表中的键,在这种情况下,您将其复制到结果列表中,否则使用当前日期创建一个新结果项,为项目计数创建0。
让我知道这个概念验证是适合你的,如果不是,我会尝试建立一个例子。
修改:您编辑了自己的问题,提到您已经拥有开始和结束之间所有日期的列表,因此您可以跳过第2步。 :)
答案 2 :(得分:0)
从第一个日期开始使用DateTime.AddDays,并在从第一个日期到最后一个日期循环时填写空格?
答案 3 :(得分:0)
假设您有一个列表,其中包含从最小日期到最大日期范围内的所有日期,称为alldates,您可以执行以下操作:
var transactions = new List<Data>(originalData);
transactions.AddRange(from dt in
alldates.Except
(
from t in transactions
select t.TransactionDate
)
select new Data() { TransactionDate = dt, ItemCount = 0 });
其中数据定义为:
class Data
{
public DateTime TransactionDate { get; set; }
public int ItemCount { get; set; }
}