[英]Linq produce a list of missing records for a given date range
假設我有以下類的列表:
public class Holding
{
public string HoldingId{ get; set; }
public DateTime date { get; set; }
}
在給定的日期范圍內,每天需要持有一個持有者。 我需要能夠生成該范圍缺失的館藏列表。
所以說我有以下數據需要檢查2010年6月1日至2010年6月5日的范圍:
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
我使用以下問題的答案生成了日期列表范圍: 查找給定范圍的缺失日期 。
我不能完全理解如何從這里前進......我假設我需要通過HoldingId進行分組以生成一系列日期,然后執行range.Except(holdings.dates)或其他類似的效果。
有沒有人使用Linq有一個很好的解決這個問題的方法?
你應該怎么做才是對的; 這是我得到的;
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);
}
另一種方法:
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;
}
一個純粹的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()
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.