Reputation: 3318
I have a sorted dictionary that looks like such:
SortedDictionary<DateTime, string> mySortedDictionary = GetDataSource();
To get the last element, I noticed that I am able to do this:
DateTime last = Convert.ToDateTime(mySortedDictionary.Keys.Last());
Is there any way to get the second-to-last item? The way that I am currently thinking of involves getting the last item and then calculating what the second to last item would be. My DateTime keys all have a set pattern, however, it is not guaranteed that I know them exactly.
Upvotes: 3
Views: 4107
Reputation: 11403
Using linq you can skip all items until the second to last and take the first one (but first check if the dictionary has at least 2 elements):
var secondToLast = mySortedDictionary.Skip(mySortedDictionary.Count - 2).First();
Upvotes: 3
Reputation: 171246
Can you store the keys reversed? In that case you can just use mySortedDictionary.Skip(1).FirstOrDefault()
.
You can reverse the key sort order by specifying a (simple) custom IComparer
in the constructor.
Upvotes: 0
Reputation: 59705
dictionary.Keys.Reverse().Skip(1).FirstOrDefault()
This will take O(n)
time, but I as far as I can tell there seems to be no fast solution.
Upvotes: 3
Reputation: 203838
You can use this method to get the second to last item. Note that it needs to iterate the entire sequence of keys to get it, so it will not be efficient. Also note that I've mostly ignored the cases of a 0 or 1 item sequence; you can check for it and throw, or do something else, if you don't want to be given the default value.
public static T SecondToLast<T>(this IEnumerable<T> source)
{
T previous = default(T);
T current = default(T);
foreach (var item in source)
{
previous = current;
current = item;
}
return previous;
}
To use it:
DateTime secondToLast = mySortedDictionary.Keys.SecondToLast();
Upvotes: 0