我会使用自定义结构和集合来存储这些信息:
public struct DateValue
{
public DateValue(DateTime date, double val)
: this()
{
this.Date = date;
this.Value = val;
}
public DateTime Date { get; set; }
}
这是一个集合的可能实现,它包含所有DateValues 并封装返回最近的逻辑。它使用List.BinarySearch 来查找它。如果它没有找到直接匹配,它使用BinarySearch 的逻辑来检测最近的是:
指定值在指定数组中的索引,如果值为
成立。如果未找到值且值小于一个或多个
数组中的元素,一个负数,它是按位补码
大于 value 的第一个元素的索引。如果值
未找到且值大于数组中的任何元素,a
负数,它是(的索引的按位补码
最后一个元素加 1)。
public class DateValueCollection : List<DateValue>, IComparer<DateValue>
{
public DateValueCollection() { }
public DateValueCollection(IEnumerable<DateValue> dateValues, bool isOrdered)
{
if (isOrdered)
base.AddRange(dateValues);
else
base.AddRange(dateValues.OrderBy(dv => dv.Date));
}
public DateValue GetNearest(DateTime date)
{
if (base.Count == 0)
return default(DateValue);
DateValue dv = new DateValue(date, 0);
int index = base.BinarySearch(dv, this);
if (index >= 0)
{
return base[index];
}
// If not found, List.BinarySearch returns the complement of the index
index = ~index;
DateValue[] all;
if(index >= base.Count - 1)
{
// proposed index is last, check previous and last
all = new[] { base[base.Count - 1], base[base.Count - 2] };
}
else if(index == 0)
{
// proposed index is first, check first and second
all = new[] { base[index], base[index + 1] };
}
else
{
// return nearest DateValue from previous and this
var thisDV = base[index];
var prevDV = base[index - 1];
all = new[]{ thisDV, prevDV };
}
return all.OrderBy(x => (x.Date - date).Duration()).First();
}
public int Compare(DateValue x, DateValue y)
{
return x.Date.CompareTo(y.Date);
}
}
快速测试:
var dateVals = new[] {
new DateValue(DateTime.Today.AddDays(10), 1), new DateValue(DateTime.Today, 3), new DateValue(DateTime.Today.AddDays(4), 7)
};
var dvCollection = new DateValueCollection(dateVals, false);
DateValue nearest = dvCollection.GetNearest(DateTime.Today.AddDays(1));