Domanda

Diciamo che ho un oggetto Dictionary:

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

Ora voglio scorrere il dizionario in ordine inverso.Non posso usare un semplice ciclo for, perchè non conosco le chiavi del dizionario.Un foreach è facile:

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

Ma come è possibile eseguire questo in senso inverso?

È stato utile?

Soluzione

Mi piacerebbe utilizzare un SortedList invece di un dizionario.È ancora possibile accedervi dalla Chiave, ma è possibile accedervi dall'indice di.

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 notare che l'ordinamento di una lista negozi di coppie chiave/valore ordinati da sola chiave.

Altri suggerimenti

Un dizionario o di qualsiasi altra forma di tabella hash non ha alcun ordine.Così che cosa stai cercando di fare è inutile :)

Se si dispone di .NET 3.5, è possibile utilizzare il .Reverse() metodo di estensione IEnumerables.Per esempio:

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

In realtà, in C# 2.0 è possibile creare il proprio iteratore che attraversa un contenitore in senso inverso.Quindi, è possibile utilizzare che iteratore nella vostra istruzione foreach.Ma l'iteratore dovrebbe avere un modo di navigare il contenitore, in primo luogo.Se si tratta di un semplice array, si potrebbe andare all'indietro come questo:

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

Ma, naturalmente, non si può fare con un Dizionario di non implementare IList o fornisce un indicizzatore.Dire che un Dizionario non avere fine non è vero:ovviamente non ha fine.L'ordine può anche essere utile se si sa di cosa si tratta.

Per una soluzione al tuo problema:Direi che copia gli elementi di un array, e utilizzare il metodo di cui sopra per la attraversano in senso inverso.Come questa:

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);
    }

}

La copia dei valori di un array può sembrare una cattiva idea, ma a seconda del tipo di valore non è davvero male.Si potrebbe semplicemente essere la copia di riferimenti!

Sono d'accordo con @leppie, ma pensi di meritare una risposta alla domanda in generale.Potrebbe essere che hai fatto per la domanda, per essere in generale, ma accidentalmente preso una brutta struttura di dati.L'ordine dei valori in un dizionario dovrebbe essere considerato l'implementazione specifica;secondo la documentazione è sempre lo stesso ordine di come le chiavi, ma questo ordine non è specificato come bene.

Comunque, non c'è un modo semplice per rendere foreach funzionano in modo inverso.È " zucchero sintattico per l'utilizzo della classe enumeratore, e enumeratori può viaggiare solo in una direzione.Tecnicamente la risposta potrebbe essere "invertire la raccolta, quindi enumerare", ma credo che questo sia un caso in cui dovrete semplicemente utilizzare un "indietro" per il ciclo:

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

Se non si dispone di .NET 3.5 e quindi Invertire il metodo di estensione è possibile implementare il proprio.Direi che probabilmente genera un intermedio elenco (quando necessario) e scorre in senso inverso, qualcosa di simile al seguente:

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];
    }
}

Che sarebbe un Dictionary<int, SomeObject> myDictionary, e si dovrebbe fare da parte:

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

L'unico modo che posso venire con in .NET 2.0 è di copiare tutti i valori di un Elenco, per invertire la lista e quindi eseguire il foreach su questa 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
}

Se l'ordine è più importante, si potrebbe si una Pila e creare una semplice struttura per memorizzare i vostri int, coppia di Oggetti.

Se si desidera un tipo di dizionario collezione, ma è necessario mantenere l'ordine di inserimento dei dati si può guardare in KeyedCollection qui

Si tratta di una fusione tra un dizionario e un elenco.In questo modo è possibile accedere agli elementi della collezione via la chiave o l'inserimento di un indice.

L'unico aspetto negativo è che se il tuo elemento è memorizzato nella collezione deve avere una chiave di tipo int.Se si potesse cambiare il tipo di una stringa o di un altro tipo (Guid Mabye).Dal momento che la raccolta1 sarà essere ricerca per la chiave di 1 piuttosto che l'indice di 1.

Standard for ciclo potrebbe essere migliore.Non si deve preoccupare l'overhead di elaborazione di invertire la raccolta.

È possibile utilizzare il LINQ to Objects Enumerabile.Funzione Reverse() in .NET 2.0 utilizzando LinqBridge.

Letterale risposta:

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top