我有一个SortedList,每10分钟添加一次KeyValuePairs。我正在尝试保留最近的10个KeyValuePair,并删除所有先前的对,但是我正在做的事情不起作用。下面,我在每个步骤中附加了我的代码和解释。任何帮助将不胜感激。
private SortedList<int, double> myList = new SortedList<int, double>();
// Every 10 minutes a new KeyValuePair is added to myList so
// I have no issue with sorting. I'm only trying to get the most
// recent 10 KeyValuePairs.
// My Attempt (the only one that worked without errors)
int mylistCount = 10;
if (myList.Count()>mylistCount)
{myList.Clear();}
// The issue with my attempt is that it erases the entire myList
// As a result, whenever myList reaches 10, it goes back to Zero.
// What I'm trying to do is keep myList Count at 10 containing only
// the most recent KeyValuePairs.
** 在myList中,键的int是PlayerID#(是随机的),值是该玩家的得分%
要回答您的问题:
答案 0 :(得分:2)
我想做的是将myList Count保持为10,仅包含 最新的KeyValuePair。
您想保留最近的10对,所以我认为排序是按加法时间进行的。如果是这样,则无需对它们进行排序,因此不需要SortedList
。您可以按照评论中的建议使用Queue
。
队列是先进先出(FIFO)。这意味着您知道队列中的第一个元素是最旧的,当第十一个元素进入时您需要将其出队。例如,这难道不需花太多时间就可以完成吗?
// q is a Queue (FIFO)
if (q.Count == 10)
{
// we've reached our cap, remove the element at the
// front of the q (the oldest one)
q.Dequeue();
}
// we'll always add the newest element to the end of the q
q.Enqueue(new KeyValuePair<int, double>(key, value));
答案 1 :(得分:1)
在不了解密钥的情况下,我提供了一个简单的解决方案:
创建一个表示值及其添加时间的类,并实现f2.txt
接口:
IComparable<T>
更改列表以存储此类型:
public class TimeStampedDouble : IComparable<TimeStampedDouble>
{
public TimeStampedDouble(double value)
{
Value = value;
Date = DateTime.Now;
}
public double Value { get; private set; }
public DateTime Date { get; private set; }
public int CompareTo(TimeStampedDouble other)
{
return this.Date.CompareTo(other.Date);
}
// User-defined conversion to double, for convenience
public static implicit operator double(TimeStampedDouble d)
{
return d.Value;
}
}
使用新类将项目添加到列表中:
SortedList<int, TimeStampedDouble> list = new SortedList<int, TimeStampedDouble>();
您现在可以使用Linq获取最早的商品并将其删除:
//In this line, 1 is the key, 6 is the double you are storing.
myList.Add(1, new TimeStampedDouble(6));
myList.Add(3, new TimeStampedDouble(5));
myList.Add(2, new TimeStampedDouble(4));
myList.Add(7, new TimeStampedDouble(3));
myList.Add(5, new TimeStampedDouble(2));
键为if (myList.Count() > mylistCount)
{
var oldest = myList.OrderByDescending(i => i.Value).FirstOrDefault();
myList.Remove(oldest.Key);
}
的项目被删除。
没有必要检查5
是否为oldest
,因为a)它是一种值类型,b)检查最少项目数,因此假设该列表将始终如果null
大于mylistCount
,则至少有一项。
由于提供了对0
的隐式转换,因此可以使用该值而无需显式强制转换:
double
答案 2 :(得分:1)
如何使用LinkedList而不是SortedList。
if(myLinkedList.Count() > 10)
myLinkedList.RemoveFirst();
这将始终删除列表中第一个添加的项目。
答案 3 :(得分:0)
我认为最方便的解决方案是使用有界列表,以确保列表中的元素永远不会超过最大数量。实现这样的列表不是很困难。可能最灵活的方法是实现IDictionary<TKey, TValue>
接口,将工作委派给内部SortedList<TKey, TValue>
。贝娄是一种基于继承的方法,需要更少的代码。每次添加元素使Count
变得大于boundedCapacity
时,列表中最旧的元素都会自动删除。
public class BoundedSortedList<TKey, TValue> : SortedList<TKey, TValue>
{
private readonly int _boundedCapacity;
private readonly List<TKey> _queue = new List<TKey>();
public BoundedSortedList(int boundedCapacity)
{
_boundedCapacity = boundedCapacity;
}
public new void Add(TKey key, TValue value)
{
base.Add(key, value);
_queue.Add(key);
if (this.Count > _boundedCapacity)
{
var keyToRemove = _queue[0];
this.Remove(keyToRemove);
}
}
public new TValue this[TKey key]
{
get { return base[key]; }
set { this.Remove(key); this.Add(key, value); }
}
public new bool Remove(TKey key) { _queue.Remove(key); return base.Remove(key); }
public new bool RemoveAt(int index) => throw new NotImplementedException();
public new void Clear() { base.Clear(); _queue.Clear(); }
}
用法示例:
var myList = new BoundedSortedList<int, double>(10);
不正确的用法示例:
var myIList = (IDictionary<int, double>)myList;
这将不起作用,因为通过接口访问类将绕过使列表受限的逻辑。
答案 4 :(得分:0)
这对我有用:
if (myList.Count()>mylistCount)
{myList.Remove(myList.FirstOrDefault());}
谢谢大家