2010-07-27 23 views
7

¿Cómo obtener un Enumerator en un artículo en un diccionario ordenado usando la tecla?Tecla siguiente en C# Dictionary

Nota:GetEnumerator() obtiene un Enumerator al primer elemento ..

pero necesito para obtener una Enumerator al elemento con una clave determinada con el fin de tener acceso a los siguientes elementos usando MoveNext() por ejemplo ...

Editar: o una manera de acceder a la siguiente elementos ...

Editar: yo prefiero un método de tiempo const ...

Gracias

Respuesta

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

Dónde myKey es la clave que está buscando. Y puede usar el método de extensión OrderBy si desea tener las claves ordenadas.

Editar: No puede hacerlo en constante con Dictionary/SortedDictionary. ¿Por qué no implementar su propio árbol de búsqueda binaria (como SortedDictionary es) y tendrá O (log n) búsqueda de tiempo y O (1) tiempo .next()?

1

No puede hacer eso con Dictionary. Puede lograr eso teniendo la posibilidad de acceder por índice, para que pueda usar SortedList en lugar de Diccionario. También puedes echar un vistazo al SkipWhile.

Aunque puede tener alguna solución como esta:

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

Pero por supuesto esto no es la mejor idea.

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

Si tiene Marco> = 3.5 instalado uso SkipWhile Janus Tondering y LukeH sugirieron. Para las versiones de marco inferior, debe hacerlo usted mismo (es decir, completar un segundo diccionario con los pares de valores clave desde la clave hasta el final).

0

La opción más fácil es usar un SortedList y luego agregarle un método de extensión que devuelve un IEnumerable cuyos elementos son mayores o iguales que la clave especificada. La complejidad del método GetElementsGreaterThanOrEqual a continuación es O (log (n)) para obtener el primer elemento y luego cada iteración después de eso es 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

Cómo se utiliza este método/llama? – vapcguy

0

Tal vez esto es útil para alguien:

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 
Cuestiones relacionadas