Accessing a Dictionary.Keys Key through a numeric index

I'm using a Dictionary<string, int> where the int is a count of the key.

Now, I need to access the last-inserted Key inside the Dictionary, but I do not know the name of it. The obvious attempt:

int LastCount = mydict[mydict.keys[mydict.keys.Count]];

does not work, because Dictionary.Keys does not implement a []-indexer.

I just wonder if there is any similar class? I thought about using a Stack, but that only stores a string. I could now create my own struct and then use a Stack<MyStruct>, but I wonder if there is another alternative, essentially a Dictionary that implements an []-indexer on the Keys?


Solution 1:

As @Falanwe points out in a comment, doing something like this is incorrect:

int LastCount = mydict.Keys.ElementAt(mydict.Count -1);

You should not depend on the order of keys in a Dictionary. If you need ordering, you should use an OrderedDictionary, as suggested in this answer. The other answers on this page are interesting as well.

Solution 2:

You can use an OrderedDictionary.

Represents a collection of key/value pairs that are accessible by the key or index.

Solution 3:

A Dictionary is a Hash Table, so you have no idea the order of insertion!

If you want to know the last inserted key I would suggest extending the Dictionary to include a LastKeyInserted value.

E.g.:

public MyDictionary<K, T> : IDictionary<K, T>
{
    private IDictionary<K, T> _InnerDictionary;

    public K LastInsertedKey { get; set; }

    public MyDictionary()
    {
        _InnerDictionary = new Dictionary<K, T>();
    }

    #region Implementation of IDictionary

    public void Add(KeyValuePair<K, T> item)
    {
        _InnerDictionary.Add(item);
        LastInsertedKey = item.Key;

    }

    public void Add(K key, T value)
    {
        _InnerDictionary.Add(key, value);
        LastInsertedKey = key;
    }

    .... rest of IDictionary methods

    #endregion

}

You will run into problems however when you use .Remove() so to overcome this you will have to keep an ordered list of the keys inserted.

Solution 4:

Why don't you just extend the dictionary class to add in a last key inserted property. Something like the following maybe?

public class ExtendedDictionary : Dictionary<string, int>
{
    private int lastKeyInserted = -1;

    public int LastKeyInserted
    {
        get { return lastKeyInserted; }
        set { lastKeyInserted = value; }
    }

    public void AddNew(string s, int i)
    {
        lastKeyInserted = i;

        base.Add(s, i);
    }
}