C# - SortedList

The SortedList collection stores key-value pairs in the ascending order of key by default. SortedList class implements IDictionary & ICollection interfaces, so elements can be accessed both by key and index.

C# includes two types of SortedList, generic SortedList and non-generic SortedList. Here, we will learn about non-generic SortedList.

Important Properties and Methods of SortedList

Property Description
Capacity Gets or sets the number of elements that the SortedList instance can store.
Count Gets the number of elements actually contained in the SortedList.
IsFixedSize Gets a value indicating whether the SortedList has a fixed size.
IsReadOnly Gets a value indicating whether the SortedList is read-only.
Item Gets or sets the element at the specified key in the SortedList.
Keys Get list of keys of SortedList.
Values Get list of values in SortedList.
Method Description
Add(object key, object value) Add key-value pairs into SortedList.
Remove(object key) Removes element with the specified key.
RemoveAt(int index) Removes element at the specified index.
Contains(object key) Checks whether specified key exists in SortedList.
Clear() Removes all the elements from SortedList.
GetByIndex(int index) Returns the value by index stored in internal array
GetKey(int index) Returns the key stored at specified index in internal array
IndexOfKey(object key) Returns an index of specified key stored in internal array
IndexOfValue(object value) Returns an index of specified value stored in internal array

Add elements in SortedList

Use the Add() method to add key-value pairs into a SortedList.

Add() method signature: void Add(object key, object value)

Key cannot be null but value can be null. Also, datatype of all keys must be same, so that it can compare otherwise it will throw runtime exception.

Example: Add key-value pairs in SortedList
SortedList sortedList1 = new SortedList();
sortedList1.Add(3, "Three");
sortedList1.Add(4, "Four");
sortedList1.Add(1, "One");
sortedList1.Add(5, "Five");
sortedList1.Add(2, "Two");

SortedList sortedList2 = new SortedList();
sortedList2.Add("one", 1);
sortedList2.Add("two", 2);
sortedList2.Add("three", 3);
sortedList2.Add("four", 4);
    
SortedList sortedList3 = new SortedList();
sortedList3.Add(1.5, 100);
sortedList3.Add(3.5, 200);
sortedList3.Add(2.4, 300);
sortedList3.Add(2.3, null);
sortedList3.Add(1.1, null);
Note : Internally, SortedList maintains two object[] array, one for keys and another for values. So when you add key-value pair, it runs a binary search using the key to find an appropriate index to store a key and value in respective arrays. It re-arranges the elements when you remove the elements from it.

SortedList collection sorts the elements everytime you add the elements. So if you debug the above example, you will find keys in ascending order even if they are added randomly, as below:

SortedList in debug view

Please notice that sortedList2 sorts the key in alphabetical order for string key in the above image.

Use Object Initializer Syntax to initialize the SortedList, as shown below.

Example: Add key-value pairs in SortedList
SortedList sortedList = new SortedList()
{
    {3, "Three"},
    {4, "Four"},
    {1, "One"},
    {5, "Five"},
    {2, "Two"}
};

SortedList key can be of any data type, but you cannot add keys of different data types in the same SortedList. The key type of the first key-value pair remains the same for all other key-value pairs. The following example will throw run time exception because we are trying to add the second item with a string key:

Example: Key of different datatypes throws exception:
SortedList sortedList = new SortedList();

sortedList.Add(3, "Three");
sortedList.Add("Four", "Four"); // Throw exception: InvalidOperationException
sortedList.Add(1, "One");
sortedList.Add(8, "Five");
sortedList.Add(2, "Two");

Access SortedList

SortedList can be accessed by index or key. Unlike other collection, SortedList requires key instead of index to access a value for that key.

Example: Access SortedList
SortedList sortedList = new SortedList()
                            {
                                {"one", 1},
                                {"two", 2},
                                {"three", 3},
                                {"four", "Four"}
                            }

int i = (int) sortedList["one"];
int j = (int) sortedList["two"];
string str = (string) sortedList["four"];

Console.WriteLine(i);
Console.WriteLine(j);
Console.WriteLine(str);
Output:
1
2
Four
Note : Non-generic SortedList collection can contain key and value of any data type. So values must be cast to the appropriate data type otherwise it will give compile-time error.
Example: Accessing Values using For Loop
SortedList sortedList = new SortedList()
                            {
                                {3, "Three"},
                                {4, "Four"},
                                {1, "One"},
                                {5, "Five"},
                                {2, "Two"}
                            };
for (int i = 0; i < sortedList.Count; i++)
{
    Console.WriteLine("key: {0}, value: {1}", 
        sortedList.GetKey(i), sortedList.GetByIndex(i));
}
Output:
key: 1, value: One
key: 2, value: Two
key: 3, value: Three
key: 4, value: Four
key: 5, value: Five

The foreach statement in C# can be use to access the SortedList collection. SortedList element includes both key and value. so, type of element would be DictionaryEntry rather than type of key or value.

Example: Access values using foreach
SortedList sortedList = new SortedList()
                            {
                                {3, "Three"},
                                {4, "Four"},
                                {1, "One"},
                                {5, "Five"},
                                {2, "Two"}
                            };
foreach(DictionaryEntry kvp in sortedList )
    Console.WriteLine("key: {0}, value: {1}", kvp.Key , kvp.Value );

Remove elements from SortedList

Use the Remove() or RemoveAt() method to remove elements from a SortedList.

Remove() signature: void Remove(object key)

RemoveAt() signature: void RemoveAt(int index)

Example: Remove elements in SortedList
SortedList sortedList = new SortedList();
sortedList.Add("one", 1);
sortedList.Add("two", 2);
sortedList.Add("three", 3);
sortedList.Add("four", 4);
    
sortedList.Remove("one");//removes element whose key is 'one'
sortedList.RemoveAt(0);//removes element at zero index i.e first element: four

foreach(DictionaryEntry kvp in sortedList )
    Console.WriteLine("key: {0}, value: {1}", kvp.Key , kvp.Value );
Output:
key: three, value: 3
key: two, value: 2

Check for an existing key in SortedList

The Contains() & ContainsKey() methods determine whether the specified key exists in the SortedList collection or not.

Contains() signature: bool Contains(object key)

ContainsKey() signature: bool ContainsKey(object key)

The ContainsValue() method determines whether the specified value exists in the SortedList or not.

ContainValue() signature: bool ContainValue(object value)

Example: Contains
SortedList sortedList = new SortedList();
                            {
                                {3, "Three"},
                                {4, "Four"},
                                {1, "One"},
                                {8, "Eight"},
                                {2, "Two"}
                            };
sortedList.Contains(2); // returns true
sortedList.Contains(4); // returns true
sortedList.Contains(6); // returns false

sortedList.ContainsKey(2); // returns true
sortedList.ContainsKey(6); // returns false

sortedList.ContainsValue("One"); // returns true
sortedList.ContainsValue("Ten"); // returns false

Visit MSDN for more information on the properties and methods of SortedList.

Points to Remember :
  1. C# has generic and non-generic SortedList.
  2. SortedList stores the key-value pairs in ascending order of the key. Key must be unique and cannot be null whereas value can be null or duplicate.
  3. Non-generic SortedList stores keys and values of any data types. So values needs to be cast to appropriate data type.
  4. Key-value pair can be cast to DictionaryEntry.
  5. Access individual value using indexer. SortedList indexer accepts key to return value associated with it.