Özel bir yapıya kullanmak ve olacaktır: hız çok önemli olmasaydı Sadece şeyiyle ve vaka diğerlerinde
, gelecekte bu okumak, bunları daha basit böyle bir şey ile bunu yapabilir toplama işlemi bu bilgileri saklamak için: Burada
public struct DateValue
{
public DateValue(DateTime date, double val)
: this()
{
this.Date = date;
this.Value = val;
}
public DateTime Date { get; set; }
}
tüm
DateValues
tutan ve en yakın dönüş mantığını kapsüller bir koleksiyon olası bir uygulamasıdır. Bulmak için
List.BinarySearch
kullanıyor.
Belirtilen dizideki belirtilen değerin endeksi değeri ise bulundu: doğrudan bir eşleşme bulamazsa o hangi yakın algılamak için BinarySearch
mantığını kullanır. Değer bulunamazsa ve değer, dizideki bir veya daha fazla öğesinden daha azsa, değerden daha büyük olan ilk öğenin indeksinin bit değeri tamamlayıcısı olan negatif bir sayıdır. değeri bulunamazsa ve değer dizideki öğelerin herhangi birinden daha büyükse, bit değeri tamamlayıcısı olan negatif numarası ( son öğenin artı 1'i).
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);
}
}
Hızlı testi:
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));
_specific Ne reason_ bir 'SortedDictionary' kaçınmak gerekiyor? –
5000 büyük bir sayı değil. Ne sıklıkla bulmanız gerekiyor? –
@TimSchmelter, koleksiyonu seri hale getirilmiş json dizesi olarak saklıyorum ve sıralı sözlükleri serileştirme konusunda iyi bir deneyimim yok. Ama ben burada SortedDictionary kullanmak için en mantıklı ise, kesinlikle farklı bir yapıya dönüştürebilirim. –