2010-07-27 3 views
7

Comment obtenir un Enumerator à un article dans un dictionnaire -Sorted à l'aide de la clé?Clé suivante dans C# Dictionnaire

Note:GetEnumerator() obtient un premier élément à Enumerator ..

Mais je dois obtenir un Enumerator à l'élément avec une clé donnée afin d'accéder aux prochains éléments à l'aide MoveNext() par exemple ...

Edit: Ou un moyen d'accéder aux éléments suivants ...

Edit: Je préfère une méthode de temps const ...

Merci

Répondre

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

Où myKey est la clé que vous recherchez. Et vous pouvez utiliser la méthode d'extension OrderBy si vous voulez trier les clés.

Édition: Vous ne pouvez pas le faire en constante avec Dictionary/SortedDictionary. Pourquoi ne pas implémenter votre propre arbre de recherche binaire (comme SortedDictionary est) et vous aurez O (log n) temps de recherche et O (1) temps .next()?

1

Vous ne pouvez pas faire cela avec Dictionary. Vous pouvez accomplir cela ayant la possibilité d'accéder par index, de sorte que vous pouvez utiliser SortedList au lieu du dictionnaire. Aussi, vous pouvez jeter un oeil à SkipWhile.

Bien que vous puissiez avoir une solution de contournement comme ceci:

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. 
} 

Mais bien sûr, ce n'est pas la meilleure idée.

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

Si vous avez Framework> = 3.5 Utilisation installé SkipWhile Janus Tondering et LukeH suggéré. Pour les versions à cadre inférieur, vous devez le faire vous-même (par exemple, remplir un second dictionnaire avec les paires de clés de votre clé jusqu'à la fin).

0

L'option la plus simple consiste à utiliser un SortedList, puis d'ajouter une méthode d'extension qui renvoie un IEnumerable dont les éléments sont supérieurs ou égaux à la clé donnée. La complexité de la méthode GetElementsGreaterThanOrEqual ci-dessous est O (log (n)) pour obtenir le premier élément, puis chaque itération après 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

Comment cette méthode utiliser/appelée? – vapcguy

0

Peut-être que ce qui est utile à quelqu'un:

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 
Questions connexes