Reputation: 29536
my LINQ query returns an ordered sequence of calendar dates, and i need to output this sequence starting from the earliest date that is more that the given number of days apart from the starting date of the sequence.
the code below does that using linear search. it seems that i could use a binary search to find the beginning date if LINQ query supported this.
in this contrived example i can search the list but in my real code i am trying to avoid storing the whole sequence in memory and i prefer to use just IEnumerable.
any ideas how to make it more efficient? i have thousands of items in my query and doing linear search is just lame...
thanks konstantin
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;
}
}
}
}
Upvotes: 1
Views: 158
Reputation: 1349
If you have sorted dates IEnumerable in sortedData collection, then here how you can get select dates later than a threshold from the first date:
var threshold = TimeSpan.FromDays(1);
var filteredDates = sortedDates.SkipWhile(sd => sd - sortedDates.First() <= theshold);
It has the advantage over .Where
that it only need to go check first dates till it gets to threshold. After that it's just enumerating elements.
Note that it's IEnumerate, so you get all the benefits of lazy loading
Upvotes: 0
Reputation: 1169
Binary search would likely be better if your data set is pre-sorted or you do not know the start date of your sequence ahead of time. However if you are sorting your dates using OrderBy like your example and you do know the start date of the sequence, why not put a Where clause in to filter out the dates that don't meet your criteria before you order the sequence?
var xs = from date in dates
where (date - target).Days < 1.2
order by date
select date;
Upvotes: 3