Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort List<T> using string without Linq

Is there a way to sort a List<T> using a string like "Name desc" (same as DataTable.DefaultView.Sort) rather then Linq?

I'm trying to replace DataTables with Lists and I need it to do this to be compatible with old code.

SOLUTION

using V4Vendetta's code I was able to create this extension method, tests seem to show it working.

public static void SortByString<T>(this List<T> list, string sortString)
{
    if (sortString == null) return;

    List<string> SortGroups = sortString.Split(',').ToList();

    for (int i = SortGroups.Count - 1; i >= 0; i--)// sort from the last group first
    {
        string tempColumn = SortGroups[i].Trim().Split(' ')[0];
        bool isAsc = SortGroups[i].Trim().Split(' ').Length > 1 ? SortGroups[i].Trim().Split(' ')[1].ToLower() == "asc" ? true : false : true;

        PropertyInfo propInfo = typeof(T).GetProperty(tempColumn);
        if (propInfo == null) // if null check to make sure its not just a casing issue.
        {
            foreach (PropertyInfo pi in typeof(T).GetProperties())
            {
                if(pi.Name.ToLower() == tempColumn.ToLower())
                {
                    tempColumn = pi.Name;
                    propInfo = typeof(T).GetProperty(tempColumn);
                    break;
                }
            }
        }

        if (propInfo != null)
        {
            Comparison<T> compare = delegate(T a, T b)
            {
                object valueA = isAsc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
                object valueB = isAsc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);

                return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
            };

            list.Sort(compare);
        }else{
            throw new IndexOutOfRangeException("Property: '" + tempColumn + "', does not exist in '" + typeof(T).ToString() + "'");
        }


    }
}
like image 571
g.foley Avatar asked Apr 28 '11 07:04

g.foley


2 Answers

List has some sort methods and some take a Comparison<T> that you can implement to have custom comparison an sorting

like image 153
Tony The Lion Avatar answered Oct 10 '22 16:10

Tony The Lion


There is no built-in support for this type of search as far as I know. So you will have to write your own.

It should not be too hard to parse the string. Split it on commas (,) in case you have a sort string like "name asc, age desc" and treat each as a name and a direction. Then you can use reflection on the type T to find the property to sort on and build a method that performs the needed comparison.

Look at this article on codeplex for an example: http://www.codeproject.com/KB/linq/dynamite_dynamic_sorting.aspx

like image 32
Rune Grimstad Avatar answered Oct 10 '22 18:10

Rune Grimstad