Reputation: 1888
My question is like the following question but with SortedList<Tkey, TValue>
instead of just the original SortedList
.
Return first element in SortedList in C#
There doesn't seem to be a function like GetKey()
.
Upvotes: 4
Views: 2632
Reputation: 15246
Using IEnumerable<>.Last or IEnumerable<>.LastOrDefault methods are efficient just for IList<> values. Let's look at the source code - access to the last item for not IList<> requires iterating through all items.
For more efficiency better to rely on SortedList<>.Keys or SortedList<>.Values properties with type IList<> (https://dotnetfiddle.net/MLmDIL) :
var sl = new SortedList<string, int>();
for (var i = 0; i < 50000; i++) {
sl.Add(i.ToString("X8"), i);
}
Console.WriteLine("SortedList<> is IList<>: " + (sl is IList<KeyValuePair<string, int>>));
Console.WriteLine("Keys-property in SortedList<> is IList<>: " + (sl.Keys is IList<string>));
Console.WriteLine("\n\nPerformance measurement - get last Key:");
var firstKey = sl.First().Key;
watch.Restart();
var lastKey = sl.Last().Key;
watch.Stop();
Console.WriteLine(" * Non IList<> access takes {0} (first key: {1}, last key: {2})", watch.Elapsed.TotalMilliseconds, firstKey, lastKey);
firstKey = sl.Keys.First();
watch.Restart();
lastKey = sl.Keys.Last();
watch.Stop();
Console.WriteLine(" * IList<> access takes {0} (first key: {1}, last key: {2})", watch.Elapsed.TotalMilliseconds, firstKey, lastKey);
Console.WriteLine("\n\nPerformance measurement - get last Value:");
var firstValue = sl.First().Value;
watch.Restart();
var lastValue = sl.Last().Value;
watch.Stop();
Console.WriteLine(" * Non IList<> access takes {0} (first value: {1}, last value: {2})", watch.Elapsed.TotalMilliseconds, firstValue, lastValue);
firstValue = sl.Values.First();
watch.Restart();
lastValue = sl.Values.Last();
watch.Stop();
Console.WriteLine(" * IList<> access takes {0} (first value: {1}, last value: {2})", watch.Elapsed.TotalMilliseconds, firstValue, lastValue);
Console.WriteLine("\n\nPerformance measurement - get last Value by Key:");
watch.Restart();
lastKey = sl.Keys.Last();
lastValue = sl[lastKey];
watch.Stop();
Console.WriteLine(" * IDictionary<> access takes {0} (last key: {1}, last value: {2})", watch.Elapsed.TotalMilliseconds, lastKey, lastValue);
/*
Execution result:
SortedList<> is IList<>: False
Keys-property in SortedList<> is IList<>: True
Performance measurement - get last Key:
* Non IList<> access takes 0.7146 (first key: 00000000, last key: 0000C34F)
* IList<> access takes 0.0032 (first key: 00000000, last key: 0000C34F)
Performance measurement - get last Value:
* Non IList<> access takes 0.7366 (first value: 0, last value: 49999)
* IList<> access takes 0.0003 (first value: 0, last value: 49999)
Performance measurement - get last Value by Key:
* IDictionary<> access takes 0.0036 (last key: 0000C34F, last value: 49999)
*/
Upvotes: 2
Reputation: 1705
You can simply use list.FirstOrDefault()
and list.LastOrDefault()
.
These two methods will return default(KeyValuePair<TKey,TValue>)
if the list is empty.
And it's better to use them because using list.First()
and list.Last()
will throw error in case the list was empty.
Upvotes: 9
Reputation: 38179
According to your (not so clear) question, you want to retrieve the keys of the first and last items in the list.
SortedList<TKey, TValue>
implements IEnumerable<KeyValuePair<TKey,TValue>>
so to do so:
sortedList.FirstOrDefault().Key
and
sortedList.LastOrDefault().Key
will return these keys
Edit:
As suggested by @mjwills, using the Keys
property is a better idea in terms of performance since it implements IList<TKey>
and LastOrDefault
is optimized to work on such cases (not fetching the whole collection to get to the last item):
sortedList.Keys.FirstOrDefault()
sortedList.Keys.LastOrDefault()
Upvotes: 7