累积日期范围

时间:2018-09-25 13:16:23

标签: c# datetime

我收到了日期范围的列表作为输入。其中有些是重叠,有些是 adjacent 。有没有可以累积进入日期范围的集合?

例如:

library(data.table)
setDT(df)

df[, Order := Order[1], ID]


#      ID Order
#  1:   2     1
#  2:  10     2
#  3:  70     3
#  4:  85     4
#  5:  70     3
#  6: 213     6
#  7:   2     1
#  8: 293     8
#  9:  10     2
# 10: 313    10

结果:

(2018/01/01, 2018/01/02),
(2018/02/15, 2018/03/21),
(2018/01/10, 2018/01/10), 
(2018/01/03, 2018/01/09)

2 个答案:

答案 0 :(得分:3)

不,标准库中没有此类集合。但是,您可以为其实现自定义的简单方法。前提是期间Tuple<DateTime, DateTime>

private static IEnumerable<Tuple<DateTime, DateTime>> Accumulate(
  IEnumerable<Tuple<DateTime, DateTime>> source) {

  var data = source
    .OrderBy(date => date.Item1)
    .ThenByDescending(date => date.Item2);

  DateTime left = DateTime.MinValue;  // make compiler be happy: initialization
  DateTime right = DateTime.MinValue; // -/-

  bool first = true;

  foreach (var item in data) {
    if (first) {
      left = item.Item1;
      right = item.Item2;

      first = false;
    }
    else if (right.AddDays(1) >= item.Item1) // can be combined; keep on combining
      right = item.Item2 > right ? item.Item2 : right;
    else {
      // can't be combined: return previous chunk
      yield return Tuple.Create(left, right);

      // start a new chunk
      left = item.Item1;
      right = item.Item2;
    }
  }

  // if we have a very last chunk to return, do it
  if (!first)
    yield return Tuple.Create(left, right);
}

然后

  Tuple<DateTime, DateTime>[] test = new Tuple<DateTime, DateTime>[] {
    Tuple.Create(new DateTime(2018, 01, 01), new DateTime(2018, 01, 02)),

    Tuple.Create(new DateTime(2018, 02, 15), new DateTime(2018, 03, 21)),
    Tuple.Create(new DateTime(2018, 01, 10), new DateTime(2018, 01, 10)),
    Tuple.Create(new DateTime(2018, 01, 03), new DateTime(2018, 01, 09)),
  };

  var result = Accumulate(test)
    .ToList();

  string report = string.Join("," + Environment.NewLine, result
    .Select(item => $"({item.Item1:yyyy'/'MM'/'dd}, {item.Item2:yyyy'/'MM'/'dd})"));

  Console.Write(report);

结果

(2018/01/01, 2018/01/10),
(2018/02/15, 2018/03/21)

答案 1 :(得分:0)

我不认为c#中有一个函数或容器可以自动为您执行此操作,但是您当然可以扩展某种集合来实现此目的。例如,以一个简单的列表为例,仅重写Add()方法以将现有项扩展一个范围,而不是添加一个新项(如果要使用累积日期范围所需的规则)