2013-08-06 9 views
7

Ich brauche ein Ringliste Wörterbuch, die Schlüssel und Artikel speichern können. Capacity = 50 und wenn ich #51 hinzufügen, muss der erste Artikel entfernt werden. Grundsätzlich muss es ein Wörterbuch sein, das sich wie eine Ringliste verhält.C# - Dictionary mit Verhalten einer Ring-Liste?

Gibt es etwas in .NET Framework, das das tun kann? Oder muss ich es selbst schreiben?

+2

Sie müssen um das selbst zu schreiben. Verwenden Sie einfach eine verknüpfte Liste und ein Wörterbuch darunter. –

+1

Wie Haris Hasan sagte, könnten Sie OrderedDictionary verwenden. Es handelt sich nicht um eine versiegelte Klasse, Sie könnten also davon erben und eine neue 'Insert'-Methodendefinition schreiben (http://msdn.microsoft.com/en-us/library/435f1dw2.aspx). Leider ist es nicht überschrieben, aber Sie könnten Ihre Klasse explizit verwenden. –

Antwort

1

Try this:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var rD = new RingDictionary(50); 
     for (int i = 0; i < 75; i++) 
     { 
      rD.Add(i, i); 
     } 
     foreach (var item in rD.Keys) 
     { 
      Console.WriteLine("{0} {1}", item, rD[item]); 
     } 
    } 
} 

class RingDictionary : OrderedDictionary 
{ 
    int indexKey; 

    int _capacity = 0; 
    public int Capacity 
    { 
     get { return _capacity; } 
     set 
     { 
      if (value <= 0) 
      { 
       var errorMessage = typeof(Environment) 
        .GetMethod(
         "GetResourceString", 
         System.Reflection.BindingFlags.Static | 
         System.Reflection.BindingFlags.NonPublic, 
         null, 
         new Type[] { typeof(string) }, 
         null) 
        .Invoke(null, new object[] { 
         "ArgumentOutOfRange_NegativeCapacity" 
        }).ToString(); 
       throw new ArgumentException(errorMessage); 
      } 
      _capacity = value; 
     } 
    } 

    public RingDictionary(int capacity) 
    { 
     indexKey = -1; 
     Capacity = capacity; 
    } 

    public new void Add(object key, object value) 
    { 
     indexKey++; 

     if (base.Keys.Count > _capacity) 
     { 
      for (int i = base.Keys.Count-1; i >Capacity-1 ; i--) 
      { 
       base.RemoveAt(i); 
      } 
     } 

     if (base.Keys.Count == _capacity) 
     { 
      base.RemoveAt(indexKey % _capacity); 
      base.Insert(indexKey % _capacity, key, value); 
     } 
     else 
     { 
      base.Add(key, value); 
     } 
    } 
} 
+0

Für eine bessere Leistung sollten Sie keine Werte entfernen und einfügen, sondern alte überschreiben. Außerdem werde ich deinen Weg gehen. – Bitterblue

5

Sie werden nichts finden Einbau-ich denke, aber man kann man sich leicht implementieren mit OrderedDictionary

OrderedDictionary Artikel, um unterhält, die sie eingesetzt werden. Immer wenn Sie das Limit/die Kapazität erreichen, können Sie das erste Element entfernen.

2

oder eine Erweiterungsmethode verwenden:

EDIT:

weil

neuesten Eintrag hinzugefügt zuerst zurückgegeben endet.

so u kann das erste Element entfernen wie:

dictionary.Remove(dictionary.Last().Key); 

& so Ihre Erweiterung Methode ist:

addExtension(this Dictionary<string, object> dictionary, string key, object value) 
    { 
     if(dictionary.Count == 50) 
       dictionary.Remove(dictionary.Last().Key); 

     dictionary.Add(key, value); 
    } 
+0

Parametrisierte Version: 'static void AddExtension (dieses IDictionary Wörterbuch, T-Taste, V-Wert) { dictionary.Add (Schlüssel, Wert); if (dictionary.Count == 50) dictionary.Remove (dictionary.First(). Key); } ' –

+0

Entfernen Sie nicht ein zufälliges Element aus dem' Dictionary'? Die Reihenfolge der Elemente in einem 'Dictionary' ist nicht definiert. Vielleicht könntest du sogar den Artikel löschen, den du gerade hinzugefügt hast :-) Siehe zum Beispiel http://Stackoverflow.com/a/4007787/613130 ​​ – xanatos

+0

@xanatos siehe meine Bearbeitung –