2010-07-27 14 views
7

Wie man einen Enumerator zu einem Gegenstand in einem Sorted- Wörterbuch unter Verwendung des Schlüssels erhält?Nächster Schlüssel in C# Dictionary

Hinweis:GetEnumerator() erhält ein Enumerator zum ersten Elemente ..

Aber ich brauche eine Enumerator auf das Element mit einem bestimmten Schlüssel zu erhalten, um den Zugang zum nächsten Elemente am Beispiel MoveNext() zu gewinnen ...

Edit: Oder ein Weg nächste Elemente zuzugreifen ...

Edit: ziehe ich eine konstante Zeit Methode ...

Dank

Antwort

7
var enumerator = dictionary.Keys.SkipWhile(k => k != myKey) 

Wo myKey ist der Schlüssel für Sie suchen. Und Sie können die Erweiterungsmethode OrderBy verwenden, wenn Sie die Schlüssel sortiert haben möchten.

Bearbeiten: Sie können es nicht in Konstante mit Dictionary/SortedDictionary tun. Warum implementieren Sie nicht Ihren eigenen binären Suchbaum (wie SortedDictionary ist) und Sie haben O (log n) Zeit suchen und O (1) Zeit .next()?

1

Sie können das nicht mit Dictionary tun. Sie können erreichen, dass die Möglichkeit des Zugriffs per Index, so dass Sie SortedList anstelle von Dictionary verwenden können. Sie können auch einen Blick auf SkipWhile werfen.

Obwohl Sie etwas Abhilfe wie diese haben können:

Dictionary<int, int> dictionary = new Dictionary<int, int>(); 
foreach (KeyValuePair<int, int> pair in dictionary) 
{ 
    // you can check the key you need and assume that the next one will be what you need. 
} 

Aber natürlich ist dies nicht die beste Idee.

0
var query = yourDictionary.SkipWhile(kvp => kvp.Key != keyToFind); 
foreach (var result in query) 
{ 
    // ... 
} 
1

Wenn Sie Framework> = 3.5 installiert haben, verwenden Sie SkipWhile Janus Tondering und LukeH vorgeschlagen. Für niedrigere Framework-Versionen müssen Sie es für sich selbst tun (zB füllen Sie ein zweites Wörterbuch mit den keyvaluepairs von Ihrem Schlüssel bis zum Ende).

0

Die einfachste Option besteht darin, eine SortedList zu verwenden und dann eine Erweiterungsmethode hinzuzufügen, die eine IEnumerable zurückgibt, deren Elemente größer oder gleich dem angegebenen Schlüssel sind. Die Komplexität der GetElementsGreaterThanOrEqual-Methode unten ist O (log (n)), um das erste Element zu erhalten, und dann ist jede nachfolgende Iteration O (1).

public static class SortedListExtension 
{ 
    public static IEnumerable<KeyValuePair<TKey, TValue>> GetElementsGreaterThanOrEqual<TKey, TValue>(this SortedList<TKey, TValue> instance, TKey target) where TKey : IComparable<TKey> 
    { 
     int index = instance.BinarySearch(target); 
     if (index < 0) 
     { 
      index = ~index; 
     } 
     for (int i = index; i < instance.Count; i++) 
     { 
      yield return new KeyValuePair<TKey, TValue>(instance.Keys[i], instance.Values[i]); 
     } 
    } 

    public static int BinarySearch<TKey, TValue>(this SortedList<TKey, TValue> instance, TKey target) where TKey : IComparable<TKey> 
    { 
     int lo = 0; 
     int hi = instance.Count - 1; 
     while (lo <= hi) 
     { 
      int index = lo + ((hi - lo) >> 1); 
      int compare = instance.Keys[index].CompareTo(target); 
      if (compare == 0) 
      { 
       return index; 
      } 
      else 
      { 
       if (compare < 0) 
       { 
        lo = index + 1; 
       } 
       else 
       { 
        hi = index - 1; 
       } 
      } 
     } 
     return ~lo; 
    } 
} 
+0

Wie würde dieses Verfahren verwendet werden/genannt? – vapcguy

0

Vielleicht ist das nützlich, um jemand:

public Dictionary<string, int> myDictionary = new Dictionary<string, int>(); 
public string myCurrentKey = "some key 5"; 
for (int i = 1; i <= 10; i++) { 
    myDictionary.Add(string.Format("some key {0}", i), i); 
} 

private void MoveIndex(int dir) { // param "dir" can be 1 or -1 to move index forward or backward 
    List<string> keys = new List<string>(myDictionary.Keys); 
    int newIndex = keys.IndexOf(myCurrentKey) - dir; 
    if (newIndex < 0) { 
     newIndex = myDictionary.Count - 1; 
    } else if (newIndex > myDictionary.Count - 1) { 
     newIndex = 0; 
    } 

    myCurrentKey = keys[newIndex]; 
} 

Debug.Log(string.Format("Current value: {0}", myDictionary[myCurrentKey])); // prints 5 
MoveIndex(1); 
Debug.Log(string.Format("Current value: {0}", myDictionary[myCurrentKey])); // prints 6 
MoveIndex(-1); 
MoveIndex(-1); 
Debug.Log(string.Format("Current value: {0}", myDictionary[myCurrentKey])); // prints 4 
Verwandte Themen