首页 > 解决方案 > 从字典中获取最近的可用值

问题描述

我有一本字典

Dictionary<DateTime, double> MyData  

现在我想从字典中获取值。
但是如果密钥不存在,那么我需要采用最接近的值。

让我们调用一个函数

double GetMyData(Dictionary<DateTime, double> MyData, DateTime Date)  
    {  
      if(MyData.ContainsKey(Date)  
      {
          return MyData[Date];
      }  
      else  
      {  
          //return the nearest available value.  
          // if Date is '2018-01-01', then try to look for next date,  
          // It can be '2018-01-02' or even '2017-12-31'  
          // Here aim is to get the nearest available value.
      }  
    } 

编辑:
样本数据:

MyData['2018-01-01'] = 420.0;  
MyData['2018-02-01'] = 220.0;  
MyData['2018-03-01'] = 320.0;  
MyData['2018-05-01'] = 210.0;  
MyData['2018-06-01'] = 220.0;   
MyData['2018-07-01'] = 230.0;  
MyData['2018-08-01'] = 240.0;

这里键“2018-04-01”不可用,
所以我需要任何最接近的可用值。
它可以是“2018-03-01”或“2018-05-01”的值
现在我希望它被清除。
请不要冒犯,英语不是我的母语。

标签: c#dictionary

解决方案


你需要一个有序的字典,不仅如此,你还需要一个自定义比较器来找到最接近键的日期

请参阅下面的最小示例代码

void Main()
{
    OrderedDictionaryByDateTime<double> data = new OrderedDictionaryByDateTime<double>();
    data.Add(DateTime.Now, 1.1);
    data.Add(DateTime.Now.AddDays(-1), 1.2);
    data.Add(DateTime.Now.AddDays(2), 1.3);
    data.Add(DateTime.Now.AddDays(3), 1.4);
    data.Add(DateTime.Now.AddDays(-5), 1.5);

    var tomorrow = DateTime.Now.AddDays(1);
    var oneHourBefore = DateTime.Now.AddHours(-1);
    var theDayAfterTomorrow = DateTime.Now.AddDays(2);
    var yesterday = DateTime.Now.AddDays(-1);
    var fourDaysInThePast = DateTime.Now.AddDays(-4);

    data.GetValueClosestToTheDateTimeKey(tomorrow); // should be 1.1
    data.GetValueClosestToTheDateTimeKey(oneHourBefore); // should be 1.1
    data.GetValueClosestToTheDateTimeKey(yesterday); // should be 1.2
    data.GetValueClosestToTheDateTimeKey(theDayAfterTomorrow); // should be 1.3
    data.GetValueClosestToTheDateTimeKey(fourDaysInThePast); // should be 1.5
}

public class OrderedDictionaryByDateTime<TValue> : List<KeyValuePair<DateTime, TValue>>
{
    private readonly Dictionary<DateTime, int> _dictionary = new Dictionary<DateTime, int>();

    public void Add(DateTime key, TValue value)
    {
        Add(new KeyValuePair<DateTime, TValue>(key, value));
        _dictionary.Add(key, Count - 1);
    }

    public TValue Get(DateTime key)
    {
        var idx = _dictionary[key];
        return this[idx].Value;
    }

    public TValue GetValueClosestToTheDateTimeKey(DateTime key)
    {
        var closestDate = _dictionary.Keys.OrderBy(t => Math.Abs((t - key).Ticks)).First();

        return Get(closestDate);
    }
}

推荐阅读