Sort any Collection by a certain property using Insertion Sort Algorithm in C#
Sorting is a big topic to talk about , but in IT industry you need it many time every day. My leader asked me to sort a huge collection of very complicated items.My first try take about 2 mins this is catastrophe but I kept try and try till I found a nice sorting algorithm (of course for my case) which made the sorting time became about 2 secs. Insertion Sort algorithm you can find more about it here so I will give you a sample implementation for it using C#. you can find VB.Net version here.
first, I made it for a specific datatype and a specific property which I will order by but here it is the generic version using reflection and I used this keyword to call it as extension method of my collection..
first, I made it for a specific datatype and a specific property which I will order by but here it is the generic version using reflection and I used this keyword to call it as extension method of my collection..
public static void SortCollection<T>(this List<T> items, String propertyName, String sortDirection = "asc")
{
Object tmpItem;
Object value = new Object();
Object value2 = new Object();
int j;
Boolean insertItem;
switch (sortDirection.ToLower())
{
case "asc":
{
try
{
if (items.Count > 1)
{
String itemType =
items[0].GetType().GetProperty(propertyName).GetValue(items[0], null).GetType().ToString();
for (int i = 1; i < items.Count; i++)
{
j = i - 1;
insertItem = false;
tmpItem = items[i];
value = items[i].GetType().GetProperty(propertyName).GetValue(items[i], null);
do
{
value2 = items[j].GetType().GetProperty(propertyName).GetValue(items[j], null);
if (MyComparer(value2, value, itemType) == 1)
{
items[j + 1] = items[j];
j = j - 1;
if (j < 0)
{
insertItem = true;
}
}
else
{
insertItem = true;
}
} while (insertItem);
items[j + 1] = (T) tmpItem;
}
}
}
catch (Exception ex)
{
}
break;
}
case "desc":
{
try
{
if (items.Count > 1)
{
String itemType = items[0].GetType().GetProperty(propertyName).GetValue(items[0], null).GetType().ToString();
for (int i = 1; i < items.Count; i++)
{
j = i - 1;
insertItem = false;
tmpItem = items[i];
value = items[i].GetType().GetProperty(propertyName).GetValue(items[i], null);
do
{
value2 = items[j].GetType().GetProperty(propertyName).GetValue(items[j], null);
if (MyComparer(value2, value, itemType) == -1)
{
items[j + 1] = items[j];
j = j - 1;
if (j < 0)
{
insertItem = true;
}
}
else
{
insertItem = true;
}
} while (insertItem);
items[j + 1] = (T) tmpItem;
}
}
}
catch (Exception ex)
{
}
break;
}
}
}
The following method for just comparing values with corresponding comparer according to the datatype of propertyprivate static int MyComparer(Object secondVal, Object firstVal, String itemType)
{
int result = 0;
switch (itemType)
{
case "System.Int16":
if ((Int16) secondVal > (Int16) firstVal)
return 1;
if ((Int16) secondVal < (Int16) firstVal)
return -1;
return 0;
case "System.Int32":
if ((Int32) secondVal > (Int32) firstVal)
return 1;
if ((Int32) secondVal < (Int32) firstVal)
return -1;
return 0;
case "System.Int64":
if ((Int64) secondVal > (Int64) firstVal)
return 1;
if ((Int64) secondVal < (Int64) firstVal)
return -1;
return 0;
case "System.String":
case "String":
return String.CompareOrdinal(((String) secondVal), (String) firstVal);
case "System.DateTime":
case "System.Date":
case "DateTime":
return ((DateTime) secondVal).CompareTo(((DateTime) firstVal));
}
return result;
}
Note in this sample I just ordered my collection by primitive data-types like int, String and Date if you want to order by an object you can use Linq OrederBy extension method.
Comments
Post a Comment