Это данные испытаний. Я добавил 6 октября в конец списка, чтобы убедиться, что результат выбирается только для последней установленной даты.
List<DateTime> viewDates = new List<DateTime>();
viewDates.Add(new DateTime(10, 10, 1));
viewDates.Add(new DateTime(10, 10, 3));
viewDates.Add(new DateTime(10, 10, 3));
viewDates.Add(new DateTime(10, 10, 4));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 6));
Для начала нам нужно выяснить последнюю последовательную дату:
var lastConsecutiveDate = viewDates
.Distinct()
.Reverse()
.SkipWhile(distinctDate => viewDates.Where(viewDate => (viewDate.Date == distinctDate.Date)).Count() < 2).FirstOrDefault();
У нас есть 2 варианта, чтобы использовать foreach
или LINQ
? foreach
более читабельно по сравнению с LINQ
. Я покажу обе реализации.
Это реализация для foreach
:
var consecutiveDates = new List<DateTime>();
foreach (var item in viewDates.Where(viewDate => viewDate <= lastConsecutiveDate).Distinct().OrderByDescending(a => a.Date))
{
//break if datediff is not 1
int count = consecutiveDates.Count;
if ((count > 0) && (consecutiveDates[count - 1].Date.AddDays(-1) != item.Date))
{
break;
}
consecutiveDates.Add(item);
}
Это реализация для LINQ
, менее читаемая:
var consecutiveDates = viewDates
.Where(viewDate => viewDate <= lastConsecutiveDate)
.Distinct()
.OrderByDescending(viewDate => viewDate.Date)
.Aggregate
(
new { List = new List<DateTime>() },
(result, viewDate) =>
{
int count = result.List.Count;
if ((count > 0) && (result.List[count - 1].Date.AddDays(-1) != viewDate.Date))
{
return new { result.List };
}
result.List.Add(viewDate);
return new { result.List };
},
a => a.List
);
Console.WriteLine(consecutiveDates.Count());
выведет «3».
Я ожидаю больше рефакторинга моего кода, но я ухожу на перерыв.