views:

1644

answers:

4

I have a dictionary that I normally access with a key, so I need fast random access reads. However for one function I need to process every item in the dictionary where the order is important. It seems to be working OK in tests. Is it OK to depend on the order of items in a dictionary?

A: 

No. You're better off using a SortedDictionary if you want to keep your keys in an order.

Edit: Either that, or add your keys to a linked list if you want to keep track of the order you added the items.

OJ
using a sorted dictionary has no direct correlation to iterating through items in the order they were added (see subject)
Eoin Campbell
+7  A: 

No. If you need to keep an order, you should have a list of items as well. You could encapsulate all the operations you need in your own collection class, which would update both the dictionary and the list at the same time.

It's unfortunate that .NET doesn't have a dictionary which supports this itself - it's a reasonably common request - Java does, as LinkedHashMap.

Jon Skeet
A: 

tpower, Dictionary and SortedDictionary are very similar in that they both hold a collection of objects, accessible by a key. Where they differ is in the way they are internally built.

Dictionary is faster for insertion as far as I know, whereas SortedDictionary is built on top of a binary tree search algorithm and is faster for reading back.

In both situations though, the internal order is maintained by the key order. There is nothing to guarantee that the order you iterate through the entire collection will be the same as you inserted your items.

In this case, you may need to store both a list and a dictionary for your different requirements.

Eoin Campbell
For dictionary, the order is simply not defined (and can change as the size changes); it doesn't depend on key *order* - but clearly depends on the key values, their hashes, the number of buckets, etc.
Marc Gravell
Re performance; SortedDictionary is *slower* to read; O(log n) for SortedList<,> and SortedDictionary<,>, vs O(1) for Dictionary<,>. Of the two sorted, the SortedList<,> takes less memory and is quicker to insert *pre-sorted* data (for unsorted data, SortedDictionary<,> is quicker insertion).
Marc Gravell
(slower to read based on acces by key; source: MSDN)
Marc Gravell
A: 

The documentation clearly states that "For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair<(Of <(TKey, TValue>)>) structure representing a value and its key. The order in which the items are returned is undefined." but I'm not convinced.

In all the tests I performed, the items are always ordered by insertion.

I found this strange because I also tested HashMap and LinkedHashMap (in Java) and the order in the HashMap is not correct as expected but, like Jon Skeet said, the order in LinkedHashMap is.

Can anyone point a fail test with Dictionary?

Here is the code I use to test:

        IDictionary<string, int> dic = new Dictionary<string, int>(10);

        Console.WriteLine("Adding ...");
        for (int i = 0; i < 1000000; i++)
        {
            Guid guid = Guid.NewGuid();
            dic.Add(guid.ToString(), i);
        }
        Console.WriteLine("Testing ...");

        bool first = true;
        int lastItem = 0;
        foreach (var item in dic.Values)
        {
            if (first)
            {
                first = false;
            }
            else
            {
                if (lastItem != item - 1)
                {
                    Console.WriteLine("Test Failed !");
                    break;
                }

            }
            lastItem = item;
        }
        Console.WriteLine("Done.");
bruno conde
Hmmmm... very interesting! Even if I force lots of deletes etc it stays pretty stable. Still, if the docs say "undefined", it wouldn't be a good idea to ignore them... even if it is stable today, it doesn't have to be.
Marc Gravell
You definitely cannot rely on this test to prove that the dictionary will stay sorted forever. It could be that other changes in memory or even the time between inserts/deletes can effect the order, and the only way to know for sure is to find out how the dictionary works behind the scenes, which isn't a simple task...
gillyb