2010-11-11 2 views
1

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

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

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

любые идеи, как сделать его более эффективным? У меня есть тысячи вещей в моем запросе и делать линейный поиск просто хромает ...

благодаря Константин


using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace consapp 
{ 
    static class Program 
    { 
     static void Main(string[] args) 
     { 
      var dates = new List<DateTime>(); 
      var xs = dates.OrderBy(x => x); 

      dates.Add(DateTime.Parse("11/10/11")); 
      dates.Add(DateTime.Parse("02/02/11")); 
      dates.Add(DateTime.Parse("11/24/11")); 
      dates.Add(DateTime.Parse("09/09/11")); 
      dates.Add(DateTime.Parse("11/10/11")); 

      var d = DateTime.MinValue; 
      double offset = 1.2; 

      foreach (var x in xs) 
      { 
       if (d != DateTime.MinValue) 
       { 
        offset -= (x - d).Days; 
       } 
       if (offset < 1) 
       { 
        Console.WriteLine(x.ToShortDateString()); 
       } 
       d = x; 
      } 
     } 
    } 
} 

ответ

3

Двоичный поиск, вероятно, будет лучше, если ваш набор данных предварительно сортируется или не заранее знайте дату начала вашей последовательности. Однако, если вы сортируете свои даты с помощью OrderBy, как ваш пример, и знаете дату начала последовательности, почему бы не поместить предложение Where, чтобы отфильтровать даты, которые не соответствуют вашим критериям, прежде чем заказывать последовательность?

var xs = from date in dates 
     where (date - target).Days < 1.2 
     order by date 
     select date; 
+0

это должно быть «где (дата - мишень) .Days> = Math.Truncate (смещение)» – akonsu

0

Если вы отсортированные даты IEnumerable в коллекции sortedData, то здесь, как вы можете получить выберите даты позже, чем порог с первого дня:

var threshold = TimeSpan.FromDays(1); 
var filteredDates = sortedDates.SkipWhile(sd => sd - sortedDates.First() <= theshold); 

Он имеет преимущество над .Where что это только нужно проверить первые даты, пока не достигнет порога. После этого это просто перечисление элементов.

Обратите внимание, что это IEnumerate, так что вы получите все преимущества отложенной загрузки

Смежные вопросы