How to iterate SortedList in C#
When working with collections in C#, you’ll often need to retrieve items in a specific order, particularly when keys must remain sorted. That’s where SortedList<TKey, TValue> comes in. It provides fast lookups by key while maintaining elements in sorted order.
Iterating through a SortedList in C# might seem simple, but there’s more to it than it appears. Whether you are just starting out or optimizing performance for large-scale applications, knowing how iteration actually works behind the scenes can help you write cleaner, faster and more efficient C# code.
This article explores everything about iterating a SortedList from basic looping to advanced strategies, with real-world examples and performance insights.
What is a SortedList in C#?
A SortedList<TKey, TValue> in C# is a collection that stores key-value pairs just like a Dictionary, but with one major difference :- It automatically keeps all elements sorted by their keys.
It belongs to the System.Collections.Generic namespace and offers both the efficiency of key-based lookup and the convenience of maintaining order without any extra sorting logic.
SortedList<int, string> students = new SortedList<int, string>
{
{ 3, "Amit" },
{ 1, "Raj" },
{ 2, "Sneha" }
};After insertion, the SortedList automatically arranges the elements by key:
1 -> Raj 2 -> Sneha 3 -> Amit
This means you do not need to manually sort the collection. SortedList handles it for you.
1. Using foreach loop
The simplest way to iterate a SortedList is with a foreach loop, which yields items in sorted order of key automatically.
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var sortedList = new SortedList<string,string> { {"language","C#"}, {"topic","SortedList"} ,{"label","Beginner"} };
Console.WriteLine(".......KeyValuePair........");
foreach(KeyValuePair<string,string> kvp in sortedList) {
Console.WriteLine( $"Key : {kvp.Key} Value : {kvp.Value}");
}
Console.WriteLine("............................");
foreach(var item in sortedList) {
Console.WriteLine( $"item {item} \n\t Key : {item.Key} Value : {item.Value}");
}
Console.WriteLine("....Iterate over keys.......");
foreach(var key in sortedList.Keys) {
Console.WriteLine( $"key :- {key}");
}
Console.WriteLine("....Iterate over Values.....");
foreach(var value in sortedList.Values) {
Console.WriteLine( $"Value :- {value}");
}
}
}.......KeyValuePair........ Key : label Value : Beginner Key : language Value : C# Key : topic Value : SortedList ............................ item [label, Beginner] Key : label Value : Beginner item [language, C#] Key : language Value : C# item [topic, SortedList] Key : topic Value : SortedList ....Iterate over keys....... key :- label key :- language key :- topic ....Iterate over Values..... Value :- Beginner Value :- C# Value :- SortedList
2. Using Linq (ElementAt method ) and Count Property
You can easily iterate over a SortedList in C# using LINQ’s ElementAt() method along with the Count property. This approach gives you direct access to elements by index, while maintaining the sorted order of keys.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var sortedList = new SortedList<string,string> {
{"language","C#"},
{"topic","SortedList"},
{"label","Beginner"}
};
Console.WriteLine("..........................");
for(int i=0; i<sortedList.Count; i++) {
var item = sortedList.ElementAt(i);
Console.WriteLine("Key : "+item.Key+" Value : "+item.Value);
}
Console.WriteLine(".......KeyValuePair........");
for(int i=0; i<sortedList.Count; i++) {
KeyValuePair<string , string> item = sortedList.ElementAt(i);
Console.WriteLine("Key : "+item.Key+" Value : "+item.Value);
}
}
}.......................... Key : label Value : Beginner Key : language Value : C# Key : topic Value : SortedList .......KeyValuePair........ Key : label Value : Beginner Key : language Value : C# Key : topic Value : SortedList
The items are automatically sorted by key, so iteration always follows key order.
Performance Note
- While ElementAt() is convenient, it’s O(n) per access for non-indexed collections, meaning this approach can become inefficient for large data sets.
- sortedList.Count : Accessing the Count property is O(1) -> constant time.
- sortedList.ElementAt(i) : Internally, it enumerates from the beginning of the collection up to the i element. Therefore, each call to ElementAt(i) takes O(i + 1) time.
- Total Complexity of the Loop : O(1+2+3+…+n) = O(n ^2 )
- For better performance, use a foreach loop directly on the SortedList. It’s much faster since it uses an internal enumerator.
3. Using Linq ParallelEnumerable.ForAll Method
This method invokes in parallel the specified action for each element in the source and It is an efficient way to iterate a large data set. due to parallel execution, order of processing elements will be vary every time.
Signature of ForAll :-
public static void ForAll<TSource>(
this System.Linq.ParallelQuery<TSource> source,
Action<TSource> action
);What ForAll() Does
- Runs each action in parallel threads, rather than sequentially.
- Boosts performance when processing large collections (especially CPU-bound operations).
- Does not guarantee element order, the output order may vary every time you run the program.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var sortedList = new SortedList<string,string> {
{"language","C#"},
{"topic","SortedList"},
{"label","Beginner"}
};
Console.WriteLine("..........................");
sortedList.AsParallel().ForAll(d => Console.WriteLine("item "+d+"\n\t Key : "+d.Key+" Value : "+d.Value));
}
}.......................... item [topic, SortedList] Key : topic Value : SortedList item [language, C#] Key : language Value : C# item [label, Beginner] Key : label Value : Beginner
4. Displaying with String.Join Method
The String.Join() method is a simple and powerful way to combine multiple elements of a collection into a single formatted string.
When used with a SortedList, it provides a neat way to display its keys, values or even the entire key-value pairs in sorted order.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var sortedList = new SortedList<string,string> {
{"language","C#"},
{"topic","SortedList"},
{"label","Beginner"}
};
Console.WriteLine(".....String.Join on elements.....");
Console.WriteLine(String.Join(", ", sortedList));
Console.WriteLine(".....String.Join on Keys.....");
Console.WriteLine(String.Join(",", sortedList.Keys));
Console.WriteLine(".....String.Join on Values.....");
Console.WriteLine(String.Join(",", sortedList.Values));
}
}.....String.Join on elements..... [label, Beginner], [language, C#], [topic, SortedList] .....String.Join on Keys..... label,language,topic .....String.Join on Values..... Beginner,C#,SortedList
FAQs
1. What is a SortedList in C#?
A SortedList<TKey, TValue> in C# is a collection that stores key-value pairs in sorted order by key. It allows fast lookups, insertions and deletions while maintaining sorted order automatically.
2. How do I iterate only over the keys in a SortedList?
You can loop through the Keys property:
foreach (var key in list.Keys)
{
Console.WriteLine(key);
}3. How do I iterate only over the values in a SortedList?
If you only need to access the values (and not the keys) from a SortedList, you can use its Values property.
foreach (var value in list.Values)
{
Console.WriteLine(value);
}4. Can I iterate a SortedList using an index?
Yes. A SortedList supports index-based access
for (int i = 0; i < list.Count; i++)
{
Console.WriteLine($"{list.Keys[i]}: {list.Values[i]}");
}5. Does SortedList maintain the insertion order?
No, SortedList always sorts items by key, not by insertion order. If you need insertion order, use OrderedDictionary or Dictionary (in .NET Core 3.0+ where it preserves insertion order).
6. Can I use IEnumerator to manually iterate a SortedList?
Yes, if you prefer more control
var enumerator = list.GetEnumerator();
while (enumerator.MoveNext())
{
var kvp = enumerator.Current;
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}7. How do I iterate in reverse order?
By default, a SortedList in C# stores elements in ascending order of keys. If you want to iterate it in reverse (descending) order, you can simply loop from the last index to the first.
for (int i = list.Count - 1; i >= 0; i--)
{
Console.WriteLine($"{list.Keys[i]}: {list.Values[i]}");
}8. Is iterating through a SortedList thread-safe?
No, iterating through a SortedList<TKey, TValue> is not thread-safe. If one thread modifies the list (add, remove or update) while another thread is iterating, it can throw an InvalidOperationException.
- Safe: Multiple threads can read/iterate simultaneously if no modifications occur.
- Unsafe: Any modifications during iteration (add/remove/update) can break iteration.
9. How to iterate with condition checks (filtering) efficiently?
Instead of iterating everything and checking inside the loop, you can use LINQ for cleaner code
foreach (var kvp in list.Where(kvp => kvp.Value > 2))
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}10. Can I iterate over a SortedList in a custom sort order?
SortedList is always sorted by its key comparer. To iterate in a custom order
foreach (var kvp in list.OrderByDescending(kvp => kvp.Value))
{
Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}This allows custom ordering without changing the original SortedList.
