My dictionary:
Dictionary<double, string> dic = new Dictionary<double, string>();
How can I return the last element in my dictionary?
My dictionary:
Dictionary<double, string> dic = new Dictionary<double, string>();
How can I return the last element in my dictionary?
What do you mean by Last? Do you mean Last value added?
The Dictionary<TKey,TValue>
class is an unordered collection. 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.
There is an ordered dictionary class available in the form of SortedDictionary<TKey,TValue>
. But this will be ordered based on comparison of the keys and not the order in which values were added.
EDIT
Several people have mentioned using the following LINQ style approach
var last = dictionary.Values.Last();
Be very wary about using this method. It will return the last value in the Values collection. This may or may not be the last value you added to the Dictionary. It's probably as likely to not be as it is to be.
Dictionaries are unordered collections - as such, there is no concept of a first or last element. If you are looking for a class that behaves like a dictionary but maintains the insertion order of items, consider using OrderedDictionary
.
If you are looking for a collection that sorts the items, consider using SortedDictionary<TKey,TValue>
.
If you have an existing dictionary, and you are looking for the 'last' element given some sort order, you could use linq to sort the collection, something like:
myDictionary.Values.OrderBy( x => x.Key ).Last();
By wary of using Dictionary.Keys.Last()
- while the key list is sorted using the default IComparer
for the type of the key, the value you get may not be the value you expect.
I know this question is too old to get any upvotes, but I didn't like any of the answers so will post my own in the hopes of offering another option to future readers.
Assuming you want the highest key value in a dictionary, not the last inserted:
The following did not work for me on .NET 4.0:
myDictionary.Values.OrderBy( x => x.Key ).Last();
I suspect the problem is that the 'x' represents a value in the dictionary, and a value has no key (the dictionary stores the key, the dictionary values do not). I may also be making a mistake in my usage of the technique.
Either way, this solution would be slow for large dictionaries, probably O(n log n) for CS folks, because it is sorting the entire dictionary just to get one entry. That's like rearranging your entire DVD collection just to find one specific movie.
var lastDicVal = dic.Values.Last();
is well established as a bad idea. In practice, this solution may return the last value added to the dictionary (not the highest key value), but in software engineering terms that is meaningless and should not be relied upon. Even if it works every time for the rest of eternity, it represents a time bomb in your code that depends on library implementation detail.
My solution is as follows:
var lastValue = dic[dic.Keys.Max()];
The Keys.max() function is much faster than sorting O(n) instead of O(n log n). If performance is important enough that even O(n) is too slow, the last inserted key can be tracked in a separate variable used to replace dic.Keys.Max(), which will make the entire lookup as fast as it can be, or O(1).
Note: Use of double or float as a key is not best practice and can yield surprising results which are beyond the scope of this post. Read about "epsilon" in the context of float/double values.
If you're using .NET 3.5, look at:
dic.Keys.Last()
If you want a predictable order, though, use:
IDictionary<int, string> dic = new SortedDictionary<int, string>();
Consider creating a custom collection that contains a reference in the Add
method of the custom collection. This would set a private field containing the last added key/value(or both) depending on your requirements.
Then have a Last()
method that returns this. Here's a proof of concept class to show what I mean (please don't knock the lack of interface implementation etc- it is sample code):
public class LastDictionary<TKey, TValue>
{
private Dictionary<TKey, TValue> dict;
public LastDictionary()
{
dict = new Dictionary<TKey, TValue>();
}
public void Add(TKey key, TValue value)
{
LastKey = key;
LastValue = value;
dict.Add(key, value);
}
public TKey LastKey
{
get; private set;
}
public TValue LastValue
{
get; private set;
}
}
Instead of using:
Dictionary<double, string>
...you could use:
List<KeyValuePair<double, string>>
This would allow you to use the indexer to access the element by order instead of by key.
From the docs:
For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair structure representing a value and its key. The order in which the items are returned is undefined.
So, I don't think you can rely on Dictionary
to return the last element.
Use another collection. Maybe SortedDictionary
...
If you just want the value, this should work (assuming you can use LINQ):
dic.Values.Last()
You could use:
dic.Last()
But a dictionary doesn't really have a last element (the pairs inside aren't ordered in any particular way). The last item will always be the same, but it's not obvious which element it might be.
With .Net 3.5:
string lastItem = dic.Values.Last()
string lastKey = dic.Keys.Last()
...but keep in mind that a dictionary is not ordered, so you can't count on the fact that the values will remain in the same order.
A dictionary isn't meant to be accessed in order, so first, last have no meaning. Do you want the value indexed by the highest key?
Dictionary<double, string> dic = new Dictionary<double, string>();
double highest = double.MinValue;
string result = null;
foreach(double d in dic.keys)
{
if(d > highest)
{
result = dic[d];
highest = d;
}
}
Instead of using Linq like most of the other answers suggest, you can just access the last element of any Collection object via the Count property (see ICollection.Count Property for more information).
See the code here for an example of how to use count to access the final element in any Collection (including a Dictionary):
Dictionary<double, string> dic = new Dictionary<double, string>();
var lastElementIndex = dic.Count - 1;
var lastElement = dic[lastElementIndex];
Keep in mind that this returns the last VALUE, not the key.