CoderForHire
CoderForHire

Reputation: 439

Find 2 Dates A DateTime Falls between From Dictionary

I have a dictionary where the key is a DateTime. I need to find the 2 entries in the dictionary that are closest to a given datetime.

So, I have

Dictionary<DateTime, double> columnInfos = new Dictionary<DateTime, double>();
foreach (var activity in activities)
{

    DateTime activityDate = activity.ActivityDateTime;

    // Get the 2 entries in the columnInfos dict that activityDate falls between

}

I was going to loop through the dictionary, but is that really the best way?> Anyone have a better solution?

Thanks

Upvotes: 0

Views: 909

Answers (2)

AzNjoE
AzNjoE

Reputation: 733

This should work. index-1 and index+1 will be the position in the list of the dates immediately less than and greater than the date in question.

SortedDictionary<DateTime, double> columnInfos = new SortedDictionary<DateTime, double>();

List<KeyValuePair<DateTime, double>> columnInfosList = columnInfos.ToList();

foreach (var activity in activities)
{
    DateTime activityDate = activity.ActivityDateTime;

    for (int index = 1; index < columnInfosList.Count(); index++)
    {
         if (columnInfosList[index-1].Key < activityDate && columnInfosList[index+1].Key > activityDate)
         {
              // do something with columnInfos[index-1] and columnInfos[index+1] then break so you stop searching
         }
    }
}

Upvotes: 1

Icemanind
Icemanind

Reputation: 48686

If you can change your Dictionary<T, T> to a SortedDictionary<T, T>, you can write a function like this:

private List<DateTime> FallBetween(SortedDictionary<DateTime, double> columns, DateTime activityDate)
{
    var keys = new List<DateTime>(columns.Keys);
    int index = ~(keys.BinarySearch(activityDate));

    var dates = new List<DateTime>();

    try
    {
        dates.Add(keys[index]);
    } catch { }

    try
    {
        dates.Add(keys[index - 1]);
    } catch { }

    return dates;
}

And call it like this:

SortedDictionary<DateTime, double> columnInfos = new SortedDictionary<DateTime, double>();

columnInfos.Add(DateTime.Now, 1);
columnInfos.Add(DateTime.Now.AddDays(-2), 2);
columnInfos.Add(DateTime.Now.AddDays(-4), 3);
columnInfos.Add(DateTime.Now.AddDays(2), 4);
columnInfos.Add(DateTime.Now.AddDays(4), 5);

// dates will return a list containing two dates.
// Now - 2 days and Now - 4 days.
var dates = FallBetween(columnInfos, DateTime.Now.AddDays(-3));

// date will return a list containing only one date
// because there is only one nearing neighbor.
var date = FallBetween(columnInfos, DateTime.Now.AddDays(30));

Upvotes: 1

Related Questions