1

次のクラスのリストがあるとします。

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 を使用してこの問題を解決できる人はいますか?

4

3 に答える 3

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);
}
于 2012-08-01T08:57:51.027 に答える
1

別のアプローチ:

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;
}
于 2012-08-01T09:20:10.597 に答える
1

sajの答えに触発された純粋な Linq クエリ:

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()
);
于 2012-08-01T12:28:51.610 に答える