views:

83

answers:

4

Hi,

My question is about enumerating Dictionary elements

// Dictionary definition
private Dictionary<string, string> _Dictionary = new Dictionary<string, string>();

// add values using add

_Dictionary.Add("orange", "1");
_Dictionary.Add("apple", "4");
_Dictionary.Add("cucumber", "6");

// add values using []

_Dictionary["banana"] = 7;
_Dictionary["pineapple"] = 7;

// Now lets see how elements are returned by IEnumerator
foreach (KeyValuePair<string, string> kvp in _Dictionary)
{
  Trace.Write(String.Format("{0}={1}", kvp.Key, kvp.Value));
}

In what order will be the elements enumerated? Can I force the order to be alphabetical?

+4  A: 

The order of elements in a dictionary is non-deterministic. The notion of order simply is not defined for hashtables. So don't rely on enumerating in the same order as elements were added to the dictionary. That's not guaranteed.

Quote from the doc:

For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair<TKey, TValue> structure representing a value and its key. The order in which the items are returned is undefined.

Darin Dimitrov
Isn't dictionary implemented as a tree like std::map? In that case a comparison operator or Compare() method must gurantee deterministic order and aplphabetically sorted.
Captain Comic
If you want an order to be guaranteed use `OrderedDictionary`.
Darin Dimitrov
@Darin - for this purpose, I'm guessing SortedDictionary would be more suitable than OrderedDictionary.
Freed
SortedDictionary and OrderedDictionary are both key/value pairs. In SortedDictionary these pairs are sorted by keys which is not the case for OrderedDictionary. Also values in OrderedDictionary can be accessed by using both key or index rather than only key.
Darin Dimitrov
@CaptainComic No, it's not. It is implemented as a hash-table.
paul_71
Usually we say "non-deterministic". "Indeterministic" is a philosophy term. :)
Eyal
@Eyal, fixed my post as suggested. Sorry for my poor English, not my native language and I don't really make any difference between those two terms when there obviously is :-)
Darin Dimitrov
+1  A: 

Associative arrays (aka, hash tables) are unordered, which means that the elements can be ordered in any way imaginable.

HOWEVER, you could fetch the array keys (only the keys), order that alphabetically (via a sort function) and then work on that.

I cannot give you a C# sample because I don't know the language, but this should be enough for you to go on yourself.

Tim Čas
+3  A: 

If you want the elements ordered, use an OrderedDictionary. An ordinary hastable/dictionary is ordered only in some sense of the storage layout.

Mitch Wheat
+1  A: 

The items will be returned in the order that they happen to be stored physically in the dictionary, which depends on the hash code and the order the items were added. Thus the order will seem random, and as implementations change, you should never depend on the order staying the same.

You can order the items when enumerating them:

foreach (KeyValuePair<string, string> kvp in _Dictionary.OrderBy(k => k.Value)) {
  ...
}

In framework 2.0 you would first have to put the items in a list in order to sort them:

List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>(_Dictionary);
items.Sort(delegate(KeyValuePair<string, string> x, KeyValuePair<string, string> y) { return x.Value.CompareTo(y.Value); });
foreach (KeyValuePair<string,string> kvp in items) {
  ...
}
Guffa