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..
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 property
private 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

Popular posts from this blog

ASP.Net MVC : ActionLink with bootstrap icon

ASP.Net MVC : Conditional Validation using ValidationAttribute

Android : How to change progress bar color at runtime programmatically?