I was having one requirement for sorting
Hashtable. In general you cannot choose the sort order of the items added to the
Hashtable. To sort
Hashtable best practice is to use
SortedList. You can either replace
Hashtable with
SortedList or you convert
Hashtable into
SortedList and provided your sort expression. Let's see with example. I have one class name
ContactActivity which has contact and activity associated with it. I override
ToString method to see the the value of added object.
class ContactActivity
{
public long ActivityId { get; set; }
public long ContactId { get; set; }
public override string ToString()
{
return string.Format("Contact Id : {0} => Activity Id : {1}", ContactId, ActivityId);
}
}
Now we will going to create
Hashtable and add few objects of type
ContactActivityHashtable hs = new Hashtable();
hs.Add("3", new ContactActivity() { ContactId = 3, ActivityId = 1 });
hs.Add("4", new ContactActivity() { ContactId = 4, ActivityId = 4 });
hs.Add("6", new ContactActivity() { ContactId = 6, ActivityId = 5 });
hs.Add("1", new ContactActivity() { ContactId = 1, ActivityId = 1 });
One of the constructor of
SortedList; except
IDictionary and
IComparer; Which initializes a new instance of the
SortedList class that contains elements copied from the specified dictionary, has the same initial capacity as the number of elements copied, and is sorted according to the specified
IComparer interface. We will use that constructor to build
SortedList from
Hashtable, and also will provide the logic of sorting key by implementing
IComparer interface.
Here is the class which implements
IComparer interface
public class MySort : IComparer
{
bool IsAscendingOrder = true;
#region IComparer Members
public int Compare(object x, object y)
{
if (IsAscendingOrder)
return (int.Parse(x.ToString()) - int.Parse(y.ToString()));
else
return (int.Parse(y.ToString()) - int.Parse(x.ToString()));
}
public MySort(bool blnIsAscendingOrder)
{
IsAscendingOrder = blnIsAscendingOrder;
}
#endregion
}
I added one variable to set the order of key also added constructor which used to set sort order. As in my case key will be integer so I use
int.Parse else you can use simply string comparison. Lets create one common method to prints the
Hashtable or
SortedList, as both implements
IDictionary interface we can use that to create common method.
private static void Show(IDictionary id)
{
foreach (string strKey in id.Keys)
{
Console.WriteLine(id[strKey].ToString());
}
}
So lets put all together.
Hashtable hs = new Hashtable();
hs.Add("3", new ContactActivity() { ContactId = 3, ActivityId = 1 });
hs.Add("4", new ContactActivity() { ContactId = 4, ActivityId = 4 });
hs.Add("6", new ContactActivity() { ContactId = 6, ActivityId = 5 });
hs.Add("1", new ContactActivity() { ContactId = 1, ActivityId = 1 });
Console.WriteLine("Hashtable values");
Show(hs);
Console.WriteLine("Ascending Order");
SortedList sl = new SortedList(hs, new MySort(true));
Show(sl);
Console.WriteLine("Descending Order");
Show(sl);
sl = new SortedList(hs, new MySort(false));
Let's see the output.