24

How do I get the key and value of item from OrderedDictionary by index?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Red Swan
  • 15,157
  • 43
  • 156
  • 238

3 Answers3

51
orderedDictionary.Cast<DictionaryEntry>().ElementAt(index);
Martin R-L
  • 4,039
  • 3
  • 28
  • 28
8

There is not a direct built-in way to do this. This is because for an OrderedDictionary the index is the key; if you want the actual key then you need to track it yourself. Probably the most straightforward way is to copy the keys to an indexable collection:

// dict is OrderedDictionary
object[] keys = new object[dict.Keys.Count];
dict.Keys.CopyTo(keys, 0);
for(int i = 0; i < dict.Keys.Count; i++) {
    Console.WriteLine(
        "Index = {0}, Key = {1}, Value = {2}",
        i,
        keys[i],
        dict[i]
    );
}

You could encapsulate this behavior into a new class that wraps access to the OrderedDictionary.

jason
  • 236,483
  • 35
  • 423
  • 525
  • 1
    I did same but see once: OrderedDictionary list = OrderItems; object strKey = list[e.OldIndex]; DictionaryEntry dicEntry = new DictionaryEntry(); foreach (DictionaryEntry DE in list) { if (DE.Value == strKey) { dicEntry.Key = DE.Key; dicEntry.Value = DE.Value; } } – Red Swan Feb 10 '10 at 04:47
  • @RedSwan: Where is the index? – testing Sep 12 '14 at 10:10
  • 5
    The index is definitely *not* the key - those are necessarily distinct constructs in an ``OrderedDictionary``. – Conrad Feb 26 '15 at 19:14
  • 2
    Downvoted because the index is not the key, as demonstrated in the answer by @martin-r-l – Justin Apr 01 '15 at 14:05
2

I created some extension methods that get the key by index and the value by key using the code mentioned earlier.

public static T GetKey<T>(this OrderedDictionary dictionary, int index)
{
    if (dictionary == null)
    {
        return default(T);
    }

    try
    {
        return (T)dictionary.Cast<DictionaryEntry>().ElementAt(index).Key;
    }
    catch (Exception)
    {
        return default(T);
    }
}

public static U GetValue<T, U>(this OrderedDictionary dictionary, T key)
{
    if (dictionary == null)
    {
        return default(U);
    }

    try
    {
        return (U)dictionary.Cast<DictionaryEntry>().AsQueryable().Single(kvp => ((T)kvp.Key).Equals(key)).Value;
    }
    catch (Exception)
    {
        return default(U);
    }
}
Halcyon
  • 14,631
  • 17
  • 68
  • 99
  • 2
    If your intent is to return default values if the targeted index/key is not in the dictionary you have chosen an expensive way to do it. Exceptions are very expensive relative to normal control-flow constructs like if/else. It would be much better to check for out-of-bounds indices and non-existing keys yourself than to rely on an exception happening. – Odrade Jul 02 '15 at 21:15