-2

I have an already sorted list of object (sorted by date)

public class HistoryValue{
   public DateTime Date {get;set;}
   public decimal Value {get;set;
}

Then I have a list of days, for example,

1MonthAgo, 2MonthAgo,3MonthAgo,120MonthAgo

What I need is to find the Value on date

1MonthAgo, 2MonthAgo,3MonthAgo,120MonthAgo

If the date can not be found in the list, I should return the one just before that date. It is easiest to explain in a SQL statement although I am doing the real work in c#:

select top 1 Value 
   from HistoryValueList
     where Date between @d12m-@lookbackdaymax and @d12m order by Date desc

I was thinking of using binary search, but don't think binary search will do exactly what I want. Maybe it is best do a looping and remember the closet object of each?

daxu
  • 3,514
  • 5
  • 38
  • 76
  • `but don't think binary search will do exactly what I want` Why wouldn't it? – Servy Nov 09 '17 at 15:36
  • hi, as if the date is not in the list, I will need to find the closest one next to it. Will binary search do that for me efficiently? not sure. – daxu Nov 09 '17 at 15:45
  • So then try it and find out. Don't just *assume* it won't work. – Servy Nov 09 '17 at 15:48
  • have you checked the efficiency against any other search algorithms? – Bijan Rafraf Nov 09 '17 at 15:51
  • @Servy I read through the algorithm of binary search, and don't believe the default c# implementation will do my job (will have to be some custom implementation). If you really think the default implementation will work, please prove. – daxu Nov 09 '17 at 16:10
  • @daxu Why don't you believe it will work? By the way there are a million implementation of a binary search out there, if you simply want to know how to write your own, so you don't need a new question for that either, if you actually can't use the .NET implementation. – Servy Nov 09 '17 at 16:16

3 Answers3

-1

What you want is a "lower bound" kind of algorithm (please check this question), that is, a binary search (or bisect) algorithm that finds the left most element less than or equal to your search element.

Wilfredo
  • 1,548
  • 1
  • 9
  • 9
  • think you are about right. I implemented my own binary search with memory of shortest path now. @wilfredo – daxu Nov 11 '17 at 07:47
-2

You're in luck, there is such a thing called Language Integrated Query (LINQ) which lets you run queries on objects in C# which implement IEnumerable. That includes the List<HistoryValue> you're using.

You're looking for some code like:

HistoryValue val = historyValues.FirstOrDefault(v => v.Date > dateMin && v.Date <= dateMax);

Where historyValues is your list object.

Bijan Rafraf
  • 393
  • 1
  • 7
-2

This is pretty easy in C#. I am supposing that you get all records in list of HistoryValue class from DB!

Then you will write code like this:

List<HistoryValue> list = list;  //your list get from db here!
HistoryValue historyValue = list.Where(m=>m.Date >= @12m && m.Date <= @lookbackdaymax ).First();