Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get last element in a SortedDictionary

I see this question.

How can I get the last element in a SortedDictionary in .Net 3.5.

like image 999
leora Avatar asked Oct 23 '09 12:10

leora


People also ask

How do you find the last element in a dictionary?

Adding and removing items can change what is considered to be the first and last element. Hence there is no way to get the Last element added.

How does SortedDictionary work c#?

The SortedDictionary class in C# is represented as SortedDictionary<TKey, TValue> which is comprised of keys and values collection where key represents the word and value represents the definition and this key and value pairs are sorted based on the key and this SortedDictionary<TKey, TValue> class belongs to System.

How is SortedList implemented?

Objects in a SortedList are accessible by using their keys or indexes. The keys in a SortedList must be unique and cannot be null. While a SortedDictionary is implemented using a red-black binary search tree, a SortedList is implemented using two internal arrays — one array for the keys and one for the values.

Which collection type represents a collection of key and value pairs that are sorted by keys and are accessible by keys and values?

The SortedList class represents a collection of key-and-value pairs that are sorted by the keys and are accessible by key and by index. A sorted list is a combination of an array and a hash table. It contains a list of items that can be accessed using a key or an index.


3 Answers

You can use LINQ:

var lastItem = sortedDict.Values.Last();

You can also get the last key:

var lastkey = sortedDict.Keys.Last();

You can even get the last key-value pair:

var lastKeyValuePair = sortedDict.Last();

This will give you a KeyValuePair<TKey, TValue> with Key and Value properties.

Note that this will throw an exception if the dictionary is empty; if you don't want that, call LastOrDefault.

like image 109
SLaks Avatar answered Nov 01 '22 19:11

SLaks


Last extension method will give you the result, but it will have to enumerate the entire collection to get you there. It's such a shame SortedDictionary<K, V> doesn't expose Min and Max members especially considering internally it is backed by a SortedSet<KeyValuePair<K, V>> which has Min and Max properties.

If O(n) is not desirable, you have a few options:

  1. Switch to a SortedList<K, V>. Again for some reason BCL doesn't pack this by default. You can use indexers to get max (or min) value in O(1) time. Extending with extension methods will be nice.

    //Ensure you dont call Min Linq extension method.
    public KeyValuePair<K, V> Min<K, V>(this SortedList<K, V> dict)
    {
        return new KeyValuePair<K, V>(dict.Keys[0], dict.Values[0]); //is O(1)
    }
    
    //Ensure you dont call Max Linq extension method.
    public KeyValuePair<K, V> Max<K, V>(this SortedList<K, V> dict)
    {
        var index = dict.Count - 1; //O(1) again
        return new KeyValuePair<K, V>(dict.Keys[index], dict.Values[index]);
    }
    

    SortedList<K, V> comes with other penalties. So you might want to see: What's the difference between SortedList and SortedDictionary?

  2. Write your own SortedDictionary<K, V> class. This is very trivial. Have a SortedSet<KeyValuePair<K, V>> as the internal container and base the comparison on the Key part. Something like:

    public class SortedDictionary<K, V> : IDictionary<K, V>
    {
        SortedSet<KeyValuePair<K, V>> set; //initialize with appropriate comparer
    
        public KeyValuePair<K, V> Min { get { return set.Min; } } //O(log n)
        public KeyValuePair<K, V> Max { get { return set.Max; } } //O(log n)
    }
    

    This is O(log n). Not documented, but I checked the code.

  3. Use fiddly reflection to access the backing set which is private member of SortedDictionary<K, V> class and invoke Min and Max properties. One can rely on expressions to compile a delegate and cache it for performance. It's a very poor choice to do so. Can't believe I suggested this.

  4. Rely on other implementations, for eg. For TreeDictionary<K, V> from C5. They have FindMin and FindMax both of which are O(log n)

like image 25
nawfal Avatar answered Nov 01 '22 19:11

nawfal


You can use SortedDictionary.Values.Last();

or if you want the key and the value

SortedDictionary.Last();
like image 2
kemiller2002 Avatar answered Nov 01 '22 19:11

kemiller2002