Advertisement:

Skystone Software

http://www.SkystoneSoftware.com

Scott Waletzko's Blog
An Unsorted SortedDictionary
Published: 10/31/2007
XMl / RSS

I have to admint this tip is going to seem a little strange. What I am about to show you how to do is create a SortedDictionary that doesn't sort its members. Why would I waste my time doing this, you ask? The answer is simple: I came across a need for this in the "real world" (i.e. work), and expect someone else may as well. So here it is.

First I'll explain why this was needed. As part of the Document Object Model for a new application I am working on, I created a BaseCollection class that all of the collections in the DOM inherit from. In this particular application, the collections should all be sorted, either in ascending order (based on an "Order" property of each item) or in a random order. To achieve this, the BaseCollection passes an IComparer object to the base constructor, either using one designed to sort the items in the list by Order or to randomly sort the items (NOTE: check out this article for information about how to create a custom IComparer, and this article for an example of how to randomly sort lists).

This all worked well and good until I came across some business requirements for a collection that inherited from this base class (and it had to inherit from this base class due to other business requirements) with one major difference: the items in this list must stay in the order in which they were added to the list. In other words, they cannot be sorted. Clearly to adhere to this requirement alone, it would have made much more sense to use a base class that inherited from Dictionary instead of SortedDictionary, but I was tied to my base class (and therefore SortedDictionary) and therefore stuck. After a few moments of hand-wringing and agonizing, I realized that another custom IComparer would solve all of my problems.

The following IComparer implementation, when passed to a SortedDictionary, will convert the SortedDictionary effectively to a regular Dictionary - the items in the list will remain in the order in which they were added to the list:

VB:

Class UnsortedComparer
	Implements IComparer

	Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            If (CType(x, IComparable).CompareTo(y)) = 0 Then
                Return 0
            Else
                Return -1
            End If
	End Function

End Class
			

C#:

class UnsortedComparer : IComparer
{

	public int Compare(object x, object y)
	{
		if (((IComparable)x.CompareTo(y) == 0)
			return 0;	
		else
			return 1;		
	}

}
			

Nice and simple, just the way I like it. Basically what this does is place each item at the end of the list as it is added, since that is when the comparison is done. This results in a list that is sorted according to the order in which the items were added to the list. You have to return "0" if the items are identical, otherwise accessing the list by key won't work properly (as the same algorithm that is used for sorting is used for key access).

Editor's Note: This article was originally posted earlier this year but I pulled it because the code wasn't working properly. It's been reposted now and seems to work in all situations - feel free to send me an e-mail if you have any problems with it...



Questions or Comments? .

VB to C# and C# to VB translation provided by Instant C# and Instant VB.