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() + "'");
}
}
}
List has some sort methods and some take a Comparison<T>
that you can implement to have custom comparison an sorting
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
I had tried something on these lines maybe you need to improvise it a cit for your need
private List<Employee> CreateSortList<T>(
IEnumerable<Employee> dataSource,
string fieldName, SortDirection sortDirection)
{
List<Employee> returnList = new List<Employee>();
returnList.AddRange(dataSource);
// get property from field name passed
System.Reflection.PropertyInfo propInfo = typeof(T).GetProperty(fieldName);
Comparison<Employee> compare = delegate(Employee a, Employee b)
{
bool asc = sortDirection == SortDirection.Ascending;
object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null);
object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null);
//comparing the items
return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0;
};
returnList.Sort(compare);
return returnList;
}
You need to pass in the appropriate sort direction and the fieldname which would be property of the class (in my case Employee)
Hope this helps
I've had success with the dynamic linq query library in the past: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
Look at the specialized collections name space. There should be a sorted list in there.
精彩评论