Question

Lets say I have a Dictionary object:

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

Now I want to iterate through the dictionary in reverse order. I can't use a simple for loop because I don't know the keys of the dictionary. A foreach is easy:

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

But how can I perform this in reverse?

Was it helpful?

Solution

I'd use a SortedList instead of a dictionary. You can still access it by Key, but you can access it by index as well.

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

It's worth noting that a sorted list stores key/value pairs sorted by key only.

OTHER TIPS

A dictionary or any other form of hashtable has no ordering. So what you are trying to do is pointless :)

If you have .NET 3.5 you can use the .Reverse() extension method on IEnumerables. For example:

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

Actually, in C# 2.0 you can create your own iterator that traverses a container in reverse. Then, you can use that iterator in your foreach statement. But your iterator would have to have a way of navigating the container in the first place. If it's a simple array, it could go backwards like this:

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

But of course you can't do that with a Dictionary as it doesn't implement IList or provides an indexer. Saying that a Dictionary does not have order is not true: of course it has order. That order can even be useful if you know what it is.

For a solution to your problem: I'd say copy the elements to an array, and use the above method to traverse it in reverse. Like this:

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

}

Copying your values to an array may seem like a bad idea, but depending on the type of value it's not really that bad. You might just be copying references!

I agree with @leppie, but think you deserve an answer to the question in general. It could be that you meant for the question to be in general, but accidentally picked a bad data structure. The order of the values in a dictionary should be considered implementation-specific; according to the documentation it is always the same order as the keys, but this order is unspecified as well.

Anyway, there's not a straightforward way to make foreach work in reverse. It's syntactic sugar to using the class's enumerator, and enumerators can only travel in one direction. Technically the answer could be "reverse the collection, then enumerate", but I think this is a case where you'll just have to use a "backwards" for loop:

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

If you don't have .NET 3.5 and therefore the Reverse extension method you can implement your own. I'd guess it probably generates an intermediate list (when necessary) and iterates it in reverse, something like the following:

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

That would be a Dictionary<int, SomeObject> myDictionary, and you would do it by:

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

The only way I can come up with in .NET 2.0 is to first copy all the values to a List, reverse the list and then run the foreach on that list:

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
}

If the ordering is most important, you could you a Stack and create a simple struct to store your int, Object pair.

If you want a dictionary type collection but you need to maintain the insertion order you can look into the KeyedCollection here

It is a merger between a dictionary and a list. That way you can access elements in the collection via the key or the insertion index.

The only gotcha is if your element being stored in the collection has to have an int key. If you could change that to a string or another type (Guid Mabye). Since collection1 will be searching for the key of 1 rather than the index of 1.

A standard for loop would be best. You don't have to worry about the processing overhead of reversing the collection.

You can use the LINQ to Objects Enumerable.Reverse() function in .NET 2.0 using LinqBridge.

Literal answer:

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top