More About Generics - 4.7 Reversing the Contents of a Sorted List
(Page 3 of 4 )
Problem
You want to be able to reverse the contents of a sorted list of items while also maintaining the ability to access them in both array and list styles like SortedList and the generic SortedList<T>classes provide. Neither SortedList nor SortedList<T>provides a direct way to accomplish this without reloading the list.
Solution
Use LINQ to Objects to query the SortedList<T>and apply a descending order to the information in the list. After instantiating a SortedList<TKey, TValue>, the key of which is an int and the value of which is astring, a series of unordered numbers and their text representations are inserted into the list. Those items are then displayed:
SortedList<int, string> data = new SortedList<int, string>();
data.Add(2, "two");
data.Add(5, "five");
data.Add(3, "three");
data.Add(1, "one");
foreach (KeyValuePair<int, string>kvp in data)
{
Debug.WriteLine("\t" + kvp.Key + "\t" + kvp.Value);
}
The output for the list is shown sorted in ascending order (the default):
1 one
2 two
3 three
5 five
Now the sort order is reversed by creating a query using LINQ to Objects and setting theorderbyclause todescending. The results are then displayed from the query result set:
// query ordering by descending
var query = from d in data
orderby d.Key descending
select d;
foreach (KeyValuePair<int, string> kvp in query)
{
Debug.WriteLine("\t" + kvp.Key + "\t" + kvp.Value);
}
This time the output is in descending order:
5 five
3 three
2 two
1 one
When a new item is added to the list, it is added in the ascending sort order, but by querying again after adding all of the items, you keep the ordering of the list intact:
data.Add(4, "four");
// requery ordering by descending
query = from d in data
orderby d.Key descending
select d;
foreach (KeyValuePair<int, string> kvp in query)
{
Debug.WriteLine("\t" + kvp.Key + "\t" + kvp.Value);
}
// Just go against the original list for ascending
foreach (KeyValuePair<int, string> kvp in data)
{
Debug.WriteLine("\t" + kvp.Key + "\t" + kvp.Value);
}
It can be seen that the output has both descending and ascending orders with the new item:
5 five
4 four
3 three
2 two
1 one
1 one
2 two
3 three
4 four
5 five
Discussion
A SortedList blends array and list syntax to allow for accessing the data in either format, which can be a handy thing to do. The data is accessible as key/value pairs or directly by index and will not allow duplicate keys to be added. In addition, values that are reference or nullable types can be null, but keys cannot. The items can be iterated using a foreach loop, withKeyValuePairbeing the type returned. While accessing elements of theSortedList<T>, they may only be read from. The usual iterator syntax prohibits updating or deleting elements of the list while reading, as it will invalidate the iterator.
Theorderby clause in the query causes the result set of the query to be ordered either inascending(the default) ordescendingorder. This sorting is accomplished through use of the default comparer for the element type, so it can be affected by overriding theEqualsmethod for elements that are custom classes. Multiple keys can be specified for theorderbyclause, which has the effect of nesting the sort order such as sorting by “last name” and then “first name.”
See Also
The “SortedList,” “Generic KeyValuePair Structure,” and “Generic SortedList” topics in the MSDN documentation.
Next: 4.8 Making Read-Only Collections the Generic Way >>
More C# Articles
More By O'Reilly Media
|
This article is excerpted from chapter four of the C# 3.0 Cookbook, Third Edition, written by Jay Hilyard and Stephen Teilhet (O'Reilly, 2008; ISBN: 059651610X). Check it out today at your favorite bookstore. Buy this book now.
|
|