2016-07-10 2 views
1

У меня есть список дат:DateTime Список найти последнюю дату, что до текущего

var dates = new List<DateTime> 
     { 
      new DateTime(2016, 01, 01), 
      new DateTime(2016, 02, 01), 
      new DateTime(2016, 03, 01), 
      new DateTime(2016, 04, 01), 
      new DateTime(2016, 05, 01) 
     }; 

Теперь дается определенная датой, «StartDate». Самый простой способ создать список дат после даты начала и последней даты раньше?

I.E. - Если бы я поставить дату DateTime (2016, 03, 15), мне нужно вернуть

DateTime(2016, 03, 01), 
DateTime(2016, 04, 01), 
DateTime(2016, 05, 01) 

Это может быть столь же просто, как найти последнюю «Active» дата, а затем просто используя, где с этой даты. Но я не уверен, как это сделать, не сделав это действительно сложным.

+1

Почему первые два не будут присутствовать? Все ваши даты после даты начала ... ваш пример очень неясен. –

+0

@JonSkeet Что вы имеете в виду? У меня есть список дат с января по май. И моя дата начала 15 марта? Поэтому я хочу только вернуться в марте, апреле и мае. –

+1

Как 'date.Where (d => d> startDate) .Union (date.Max (d => d stuartd

ответ

0

Без осложнений и если я правильно понимаю ваши требования. Вы хотите, чтобы все даты после StartDate и последняя запись перед первым совпадением (If Any). Тогда я нахожу это самый простой самый читаемый способ сделать это:

var results = dates.FindAll(x => x >= StartDate); 
int index = dates.FindLastIndex(x => x < StartDate); 

// there might be no match, if all the list is resulted 
if (index >= 0) 
    results.Insert(0, dates[index]); 

Если вы предпочитаете один стиль запроса, вы можете сделать ниже (я считаю, что не читается):

var results = dates.Where(x => x >= StartDate) 
        .Concat(dates.Where(x => x < StartDate) 
           .OrderByDescending(x => x).Take(1)); 

Последняя альтернатива, если вам нравятся причудливые способы:

int startIndex = dates.FindLastIndex(x=> x < StartDate); 
startIndex = Math.Max(0, startIndex); 

var results = dates.Skip(startIndex).ToList(); 
+0

Я закончил с помощью этого метода :) Спасибо :) –

1

Если список уже отсортирован, вы можете использовать бинарный поиск:

var index = dates.BinarySearch(start); 
// If the precise value isn't found, index will be the bitwise complement 
// of the first index *later* than the target, so we need to subtract 1. 
// But if there were no values earlier, we should start from 0. 
if (index < 0) 
{ 
    index = Math.Max(~index - 1, 0); 
} 
return dates.Skip(index).ToList(); 

Это предполагает, что даты являются уникальными. Если количество дат совпадает с start, нет никакой гарантии, что он найдет первый. Если это вызывает беспокойство, вам нужно искать назад, пока не найдете первый матч.

Вы не указали, есть ли точное соответствие, вы хотите включить дату до этого или нет. Если вы это сделаете, вам нужно немного изменить этот код.

0
var partialResult = dates.Where(x => x >= date).ToList(); 
partialResult.Add(dates.Where(x => x < date).Max()); 
IList<DateTime> result = partialResult.OrderBy(x => x).ToList(); 
Смежные вопросы