Pregunta

Digamos que tengo un Diccionario de objetos:

Dictionary myDictionary<int, SomeObject> = new Dictionary<string, SomeObject>();

Ahora quiero recorrer el diccionario en orden inverso.Yo no puedo usar un simple bucle for, porque no sé las claves del diccionario.Un foreach es fácil:

foreach (SomeObject object in myDictionary.Values)
{
    // Do stuff to object
}

Pero ¿cómo puedo realizar esta marcha atrás?

¿Fue útil?

Solución

Yo uso un SortedList en lugar de un diccionario.Usted todavía puede tener acceso por Clave, pero puede acceder a él por el índice.

SortedList sCol = new SortedList();

sCol.Add("bee", "Some extended string matching bee");
sCol.Add("ay", "value matching ay");
sCol.Add("cee", "Just a standard cee");

// Go through it backwards.
for (int i = sCol.Count - 1; i >=0 ; i--)
    Console.WriteLine("sCol[" + i.ToString() + "] = " + sCol.GetByIndex(i));

// Reference By Key
foreach (string i in sCol.Keys)
    Console.WriteLine("sCol[" + i + "] = " + sCol[i]);

// Enumerate all values
foreach (string i in sCol.Values)
    Console.WriteLine(i);

Vale la pena señalar que una lista ordenada de tiendas de pares clave/valor ordenados por clave.

Otros consejos

Un diccionario o cualquier otra forma de tabla hash no tiene ningún pedido.Así que lo que están tratando de hacer es inútil :)

Si usted tiene .NET 3.5 se puede utilizar el .Reverse() método de extensión en IEnumerables.Por ejemplo:

foeach (SomeObject o in myDictionary.Values.Reverse())
{
     // Do stuff to object
}

De hecho, en C# 2.0 puede crear su propio iterador que recorre un contenedor en el reverso.A continuación, puede utilizar ese iterador en su instrucción foreach.Pero su iterador tendría que haber una forma de navegar el contenedor en el primer lugar.Si es una matriz simple, podría ir hacia atrás como esta:

static IEnumerable<T> CreateReverseIterator<T>(IList<T> list)
{
    int count = list.Count;
    for (int i = count - 1; i >= 0; --i)
    {
        yield return list[i];
    }
}

Pero, por supuesto, usted no puede hacer eso con un Diccionario, ya que no implementar la interfaz IList o proporciona un indizador.Decir que un Diccionario no tiene fin no es cierto:por supuesto que ha pedido.Ese orden puede incluso ser útil si usted sabe lo que es.

Para una solución a su problema:Yo diría que copiar los elementos de una matriz, y utilizar el método anterior para recorrer a la inversa.Como este:

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "value1";
    dict[2] = "value2";
    dict[3] = "value3";

    foreach (KeyValuePair<int, string> item in dict)
    {
        Console.WriteLine("Key : {0}, Value: {1}", new object[] { item.Key, item.Value });
    }

    string[] values = new string[dict.Values.Count];
    dict.Values.CopyTo(values, 0);

    foreach (string value in CreateReverseIterator(values))
    {
        Console.WriteLine("Value: {0}", value);
    }

}

Copiar los valores de un array puede parecer una mala idea, pero dependiendo del tipo de valor que en realidad no es malo.Puede ser que la copia de las referencias!

Estoy de acuerdo con @leppie, pero creo que te mereces una respuesta a la pregunta en general.Podría ser que la pregunta en general, pero accidentalmente escogí una mala estructura de datos.El orden de los valores de un diccionario debe ser considerado como específico de la implementación;de acuerdo a la documentación es siempre el mismo orden de las teclas, pero esta orden no se ha especificado así.

De todos modos, no hay una manera sencilla de hacer foreach funciona a la inversa.Es azúcar sintáctico para uso de la clase del enumerador, y los enumeradores sólo pueden viajar en una sola dirección.Técnicamente, la respuesta podría ser "revertir la colección, a continuación, enumerar", pero creo que este es un caso en donde usted sólo tendrá que utilizar un "retroceso" bucle for:

for (int i = myCollection.Length - 1; i >= 0; i--)
{
    // do something
}

Si usted no tiene .NET 3.5 y, por tanto, la Inversa del método de extensión puede implementar su propio.Me imagino que probablemente genera un intermedio de la lista (cuando sea necesario) y recorre a la inversa, algo como lo siguiente:

public static IEnumerable<T> Reverse<T>(IEnumerable<T> items)
{
    IList<T> list = items as IList<T>;
    if (list == null) list = new List<T>(items);
    for (int i = list.Count - 1; i >= 0; i-- )
    {
        yield return list[i];
    }
}

Que sería un Dictionary<int, SomeObject> myDictionary, y lo haría por:

foreach(SomeObject _object in myDictionary.Values.Reverse())
{
}

La única manera que se me puede venir para arriba con en .NET 2.0 es primera copia todos los valores a una Lista, invertir la lista y, a continuación, ejecute el foreach en esa lista:

Dictionary<int, object> d;
List<object> tmplist;
foreach (object o in d.Values) tmplist.Add(s);
tmplist.Reverse();
foreach (object o in tmplist) {
    //Do stuff
}

Si el orden es el más importante, usted podría una Pila y crear una simple estructura para almacenar su int, Objeto de par.

Si desea un tipo de diccionario de la colección, pero que necesita para mantener el orden de inserción usted puede mirar en el KeyedCollection aquí

Es una fusión entre un diccionario y una lista.De esa manera usted puede tener acceso a los elementos de la colección a través de la clave o la inserción de índice.

El único problema es que si el elemento que se está almacenado en la colección tiene que tener un int clave.Si pudieras cambiar una cadena u otro tipo (Guid Mabye).Desde la colección de1 será la búsqueda para la clave de 1 más que el índice de 1.

Un estándar for circuito podría ser mejor.Usted no tiene que preocuparse acerca de la sobrecarga de procesamiento de revertir la colección.

Usted puede utilizar el LINQ to Objects Enumerable.Reverse() función .NET 2.0, mediante LinqBridge.

Respuesta Literal:

Dictionary<int, SomeObject>  myDictionary = new Dictionary<int, SomeObject>();

foreach (var pair in myDictionary.OrderByDescending(i => i.Key))
{
    //Observe pair.Key
    //Do stuff to pair.Value
}
foreach (Sample in Samples)

try the following:

Int32 nEndingSample = Samples.Count - 1;

for (i = nEndingSample; i >= 0; i--)
{
     x = Samples[i].x;
     y = Samples[i].y;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top