2012-08-01 34 views
1

說我有下面的類的列表:的LINQ產生的失蹤記錄列表指定日期範圍內

public class Holding 
{ 
    public string HoldingId{ get; set; }  
    public DateTime date { get; set; } 
} 

需要有每天在指定日期範圍內的控股。我需要能夠生成一系列缺少範圍的持股。

所以說,我有以下數據,我需要檢查在範圍2010六月1日至6月5日2010:

HoldingId Date 
1   01-06-2010 
1   02-06-2010 
1   04-06-2010 
2   02-06-2010 
2   03-06-2010 
2   05-06-2010 
3   03-06-2010 

對於這組數據的丟失增持將是:

HoldingId Date 
1   03-06-2010 
1   05-06-2010 
2   01-06-2010 
2   04-06-2010  
3   01-06-2010 
3   02-06-2010 
3   04-06-2010 
3   05-06-2010 

我已經使用以下問題的答案產生了日期列表範圍: Find missing dates for a given range

我不能完全得到我圍繞着如何從這裏向前走頭......我想我需要通過HoldingId集團以生產日期的數組,然後做range.Except(holdings.dates)或有這樣的結果。

有沒有人有使用Linq這個問題的很好的解決方案?

+0

你的問題是什麼?據我所見,你需要能夠產生一個失蹤的範圍清單,你已經這樣做了。 – 2012-08-01 08:53:33

+0

這是我的問題,但我沒有解決它! – woggles 2012-08-01 08:59:05

回答

2

你完全正確的應該怎麼做;這是我得到的;

List<Holding> holdings = new List<Holding>(); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("01-06-2010"), HoldingId = "1" }); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("02-06-2010"), HoldingId = "1" }); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("04-06-2010"), HoldingId = "1" }); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("02-06-2010"), HoldingId = "2" }); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("03-06-2010"), HoldingId = "2" }); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("05-06-2010"), HoldingId = "2" }); 
holdings.Add(new Holding(){ date=Convert.ToDateTime("03-06-2010"), HoldingId = "3" }); 

List<DateTime> dateRange = new List<DateTime>(); 
dateRange.Add(Convert.ToDateTime("01-06-2010")); 
dateRange.Add(Convert.ToDateTime("02-06-2010")); 
dateRange.Add(Convert.ToDateTime("03-06-2010")); 
dateRange.Add(Convert.ToDateTime("04-06-2010")); 
dateRange.Add(Convert.ToDateTime("05-06-2010")); 

Dictionary<string, List<DateTime>> missingHoldings = new Dictionary<string, List<DateTime>>(); 

foreach(var holdGrp in holdings.GroupBy (h => h.HoldingId)) 
{ 
    var missingDates = dateRange.Except(holdGrp.Select(h => h.date)).ToList(); 
    missingHoldings.Add(holdGrp.Key, missingDates); 
} 
+0

啊,這就是我設想的方式,但我無法正確實施。謝謝saj :) – woggles 2012-08-01 09:08:58

1

的另一種方法:S:

public static List<Holding> MissingHoldings(List<Holding> existingHoldings, DateTime startDate, DateTime endDate) 
{ 
    var missingHoldings = new List<Holding>(); 
    var holdingIds = existingHoldings.Select(h => h.HoldingId).Distinct().ToList(); 
    var dates = new List<DateTime>(); 
    for (var current = startDate.Date; current <= endDate.Date; current = current.AddDays(1)) 
    { 
     dates.Add(current); 
    } 

    foreach (var holdingId in holdingIds) 
    { 
     missingHoldings 
      .AddRange(
       dates.Where(date => !existingHoldings.Any(h => h.HoldingId == holdingId && h.date == date)) 
       .Select(date => new Holding {HoldingId = holdingId, date = date})); 
    } 
    return missingHoldings; 
} 
1

純LINQ查詢由SAJ '

var missingHoldingsList = 
from h in holdings.GroupBy(h => h.HoldingId) 
from d in dateRange.Except(h.Select(x => x.date)) 
orderby h.Key, d 
select new Holding { date = d , HoldingId = h.Key }; 

SAJ的環少版本的回答' 的啓發回答:

var missingHoldingsDict = (
    from h in holdings.GroupBy(h => h.HoldingId) 
    select new 
    { 
    key = h.Key, 
    holdings = 
     from d in dateRange.Except(h.Select(x => x.date)) 
     select new Holding { date = d, HoldingId = h.Key } 
    } 
).ToDictionary(
    h => h.key, 
    h => h.holdings.ToList() 
); 
+0

很酷的變化。謝謝 :) – woggles 2012-08-01 12:40:41

相關問題