LogIn
I don't have account.

How to iterate SortedList in C#

DevSniper

128 Views

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.

Example
Copy
SortedList<int, string> students = new SortedList<int, string>
{
    { 3, "Amit" },
    { 1, "Raj" },
    { 2, "Sneha" }
};

After insertion, the SortedList automatically arranges the elements by key:

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

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

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

Copy
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:

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

Copy
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

Copy
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

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

Copy
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

Copy
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

Copy
foreach (var kvp in list.OrderByDescending(kvp => kvp.Value))
{
    Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}

This allows custom ordering without changing the original SortedList.