views:

1559

answers:

9

My dictionary:

Dictionary<double, string> dic = new Dictionary<double, string>();

How can I return the last element in my dictionary?

A: 

If you just want the value, this should work (assuming you can use LINQ):

dic.Values.Last()
Lance Harper
You can also use "dic.Last()" to get the entire key/value pair. They should work the same
Dan Herbert
A: 

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.

Jake Pearson
A: 

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.

Meta-Knight
+15  A: 

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.

JaredPar
Upvote for the warning on not using the LINQ style approach as it doesn't return what subprime requires.
RichardOD
Although there is no generic version, there is a OrderedDictionary in the System.Collection.Specialized namespace that maintains items in insertion order.
LBushkin
but if no element in the list ? how can i catch that ?
subprime
@subprime, in that case use LastOrDefault instead of Last.
JaredPar
JaredPar thanks ! it works fine!
subprime
+5  A: 

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>();
Chris Doggett
Every call to "Last()" will return the same result, until an insert or an "Add()" is made, correct? At which point it could possibly be different?
I believe so, but since it's an unordered collection, the last added may be somewhere in the middle of the collection. I'm not sure how it's implemented internally, or what Last() actually returns. Someone with more knowledge of the internals would have to answer that. Unleash the Skeet signal.
Chris Doggett
+9  A: 

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.

LBushkin
Man that's way more succinct than my answer +1;
Hardwareguy
+1  A: 

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;
}
}
RichardOD
Clever :-) You could make this more succinct by using automatic properties with private setters and public getters.
Metro Smurf
@Metro Smurf- very true, thanks. I've updated the code to include these- I believe it makes the example a little easier to read.
RichardOD
+1  A: 

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 ...

bruno conde
A: 

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;
   }
}
Hardwareguy