2009-06-12 69 views
0

假設類數據定義爲{DateTime TransactionDate,int ItemCount}。 我得到一個原始的IEnumerable包含分散的TransactionDates和ItemCounts,我需要編寫一個方法,返回一個集合,其中包含原始集合中最小和最大天數之間填充的所有天數。C# - 填寫集合中的空日期

舉例來說,如果我得到:
2009/12/5 15.00
12/7/2009 10.00
12/10/2009 75.00

我需要生成這樣的事情:
2009/12/5 15.00
2009年12月6日0.00
12/7/2009 10.00
2009/12/8 0.00
12/9/2009 0.00
12/10/2009 75.00

讓你給我一個用c#3.0做這件事的優雅方法嗎?

我有一個列表中的最小和最大日期之間的所有日期。所以我假設我所要做的就是「foreach」相交集合(allDates-existingDates)併爲每個集合插入一個新元素。我對嗎?

感謝

回答

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; 
} 
+0

您應該考慮AddDays在浮動上工作的事實。出於這個原因,我發現它有時並不準確(即增加23h59mXXs而不是一天)。 – em70 2009-06-12 08:32:41

1

假設您的收藏是一本字典(日期是獨一無二的,可以作爲按鍵),你可以做一些LIK此:

-1。確定源集合中的第一個和最後一個日期(如果集合是sortedDictionary,則有第一個和最後一個元素)。

-2。創建一個IEnumerator,它可以迭代給定開始日期和結束日期之間的所有日期。

-3。使用一個foreach結構,使用Enumerator和獲得的開始和結束日期。在每一步中,檢查當前日期是源列表中的一個鍵,在這種情況下,您將其複製到結果列表中,否則使用當前日期創建一個新結果項目,併爲項目計數創建一個0。

讓我知道這個概念證明對你來說已經足夠了,如果不是,我會試着去建立一個例子。

編輯:你編輯了你的問題,你已經有了開始和結束之間所有日期的列表,所以你可以跳過第二步。 :)

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; } 
}