Home > Software engineering >  Pull a Dictionary Entry using Date only
Pull a Dictionary Entry using Date only

Time:08-04

I have a dictionary of type Dictionary<DateTime, Cars>

In the sample dictionary below, is it possible to pick out the value for june 2nd using the date only as the Key?

 [0]: {[{31-May-2022 6:12:30 AM}, {Cars}]}
 [1]: {[{01-Jun-2022 8:52:10 AM}, {Cars}]}
 [2]: {[{02-Jun-2022 6:19:17 AM}, {Cars}]}
 [3]: {[{03-Jun-2022 6:27:39 AM}, {Cars}]}
 [4]: {[{04-Jun-2022 6:47:00 AM}, {Cars}]}

thanks!

CodePudding user response:

If you already have a Dictionary that was created without that definition of "equality", then the best you can do is iterate through the keys.

You could alternatively create the dictionary with a IEqualityComparer<DateTime> class that defines "equality" as looking at the date only:

class DateEqualityComparer : IEqualityComparer<DateTime>
{
    public bool Equals(DateTime d1, DateTime d2)
    {
        if(d1.Date == d2.Date)
            return true;
        else
            return false;
    }

    public int GetHashCode(DateTime d)
    {
        return d.Date.GetHashCode();
    }
}

Note that:

  • This class would need to be used to create the dictionary; it could not be used after the fact
  • It would prevent the dictionary from having multiple DateTime key values with the same date; Adding a key with the same date but a different time would create a collision

CodePudding user response:

You can do this with a custom IEqualityComparer<TKey> implementation if passed to your dictionary on creation.

public class DictionaryDateTimeComparer : IEqualityComparer<DateTime>
{
    public bool Equals(DateTime x, DateTime y)
    {
        return x.Date == y.Date;
    }

    public int GetHashCode(DateTime obj)
    {
        return obj.Date.GetHashCode();
    }
}

This allows you to use it like so:

var dictionary = new Dictionary<DateTime, Cars>(new DictionaryDateTimeComparer())
    {
        { DateTime.Parse("2022-05-31 6:12:30 AM"), new Cars { Id = 1 } },
        { DateTime.Parse("2022-06-01 8:53:10 AM"), new Cars { Id = 2 } }
    };
    
var car = dictionary[DateTime.Parse("2022-05-31")];

which returns the first entry.


If this is not a dictionary that you control, you can either project it to a new dictionary with:

var copiedDictionary = 
    new Dictionary<DateTime, Cars>(dictionary, new DictionaryDateTimeComparer());

or you can iterate over it which will certainly have worse performance and may not be feasible performance-wise, depending on the number of entries:

var car = dictionary.FirstOrDefault(x => x.Key.Date == DateTime.Parse("2022-05-31")).Value;

CodePudding user response:

Just a quick and dirty mockup for data, but you can use Linq to achieve this:

Dictionary<DateTime, string> cars = new Dictionary<DateTime, string>();

cars.Add(Convert.ToDateTime("31-May-2022 6:12:30 AM"), "red chevy");
cars.Add(Convert.ToDateTime("01-Jun-2022 8:52:10 AM"), "blue ford");
cars.Add(Convert.ToDateTime("02-Jun-2022 6:19:17 AM"), "green honda");

var t = cars.Where(p => p.Key.Date == Convert.ToDateTime("02-Jun-2022 01:00:00 AM").Date).SingleOrDefault().Value;
Console.WriteLine(t);

Using the .Date property of the DateTime key will only compare the dates, not time.

Obviously your result would actually be a Car object, but this is a quick way to show you get the value from the KeyValuePair object returned by Linq.

  • Related