Накопить диапазоны дат - PullRequest
       3

Накопить диапазоны дат

0 голосов
/ 25 сентября 2018

Я получаю в качестве входных данных список диапазонов дат .Некоторые из них перекрываются , некоторые смежны .Существует ли какая-либо коллекция, которая накапливает входящие диапазоны дат?

Например:

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

Результат:

(2018/01/01, 2018/01/10), // 1st, 3rd, 4th lines combined
(2018/02/15, 2018/03/21)  // 2nd line

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Нет, в стандартной библиотеке нет таких коллекций.Тем не менее, вы можете реализовать собственный простой метод для него;при условии, что период равен 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)
0 голосов
/ 25 сентября 2018

Я не думаю, что в c # есть функция или контейнер, которые будут делать это автоматически для вас, но, конечно, вы могли бы расширить какую-то коллекцию для достижения этой цели.Например, возьмите простой List и переопределите только метод Add () для расширения существующего элемента диапазоном вместо добавления нового (если применяются правила, которые вы хотите иметь для накопления диапазона дат)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...