Sebastian
Sebastian

Reputation: 514

Retrieve dictionary item by number

I have a Dictionary where the key and value are both strings. It's possible to get the value of a key by using []. But the [] expects a string. Is it possible to get the value of a key by using a number instead of the String key?

Dictionary<String, String> m_GermanEnglish = new Dictionary<String, String>();
m_GermanEnglish.Add("der", "the");

Upvotes: 0

Views: 1834

Answers (5)

Jon Senchyna
Jon Senchyna

Reputation: 8037

Using the extension functions in the System.Linq namespace, you can do the following:

var indexedDictionary = m_GermanEnglish.ToArray();
var pairAt0 = indexedDictionary[0];

You could also use the .ToList extenstion function instead of .ToArray. They both return a collection of KeyValuePair<TKey, TValue> objects.

Note: The entries in a Dictionary may not necessarily be sorted in the same order as the order they were put in.

If you need to maintain a certain ordering to your Key/Value pairs in your dictionary, you're better off using either a SortedDictionary or a SortedList. In my testing, SortedList tended to be ~2x faster on lookups and indexing by key, but SortedDictionary was ~100 times faster on removing entries.

Upvotes: 1

Sam Holder
Sam Holder

Reputation: 32936

the IDictionary interface makes no guarantees about order of the items when enumerating the dictionary, the dictionary is inherently unordered. Therefore, there is no such thing as 'the item at position 1' as the collection is unordered.

It would be valid for the items to appear in a different order each time you enumerate the dictionary.

If you need to also access the items by index then you need a different data structure, like an IOrderedDictionary implementation. there is one here which basically keeps a list side by side with the dictionary to provide access by index.

Upvotes: 6

Adam Houldsworth
Adam Houldsworth

Reputation: 64467

You cannot index into dictionaries by ordinal as items don't have an ordinal in the obvious sense, it only exposes the key as an index. Dictionaries also do not guarantee order. Add a key or remove a key, and it is indeterminate where that key will land in terms of "memory position".

If you want to get stuff out by an ordinal index, then I'd guess you need a different collection and not the Dictionary<>.

Perhaps a List<Tuple<string, string>>? Obviously this doesn't give any duplicate support, but it lets you pair items and gives you an index.

Upvotes: 3

JMarsch
JMarsch

Reputation: 21743

The order of items in a dictionary is undefined: http://msdn.microsoft.com/en-us/library/ekcfxy3x.aspx That is, the order of the values collection is only guaranteed to be in the same order as keys, but Dictionary reserves the right to change them.

Other options: You could look at the old NameObjectCollection -- it does what you are asking, but it predates generics, so it's just a dictionary of object (and if you use reflector to view the NameObjectCollection, you will see that they did the same thing -- they really implement 2 collections, a HashTable and a List).

You could store them only in a list, and search using LINQ, but wether this is a good solution depends upon how many items you need to store (dictionary lookup is O(1), List searching is going to be O(n) at best.

Upvotes: 2

Nick Babcock
Nick Babcock

Reputation: 6141

You can use LINQ

m_GermanEnglish.ElementAt(index);

But you are relying on implementation that you don't know or is guaranteed. Dictionary does not guarantee the elements to be in a certain order.

Upvotes: 4

Related Questions