5

I have a list of objects. That objects have various field, e.g. age and name

Now sometimes I'd like to sort the list by names and sometimes by age. Additional sometimes increasing order and sometimes decreasing order.

Now I understand that i should implement the Comparable interface in my object and override the CompareTo method.

But how can i do this when i want to support various sorting orders?

Do i have to set the sorting order in my object or is it somehow possible to pass the sorting order by the sort method call?

2
  • If you are using .net 3.5 and up why not use LINQ? Commented Feb 11, 2011 at 16:40
  • LINQ would also be ok :D Commented Feb 11, 2011 at 16:41

5 Answers 5

20

The method call can do everything; no need for a comparer:

list.Sort((x,y)=>string.Compare(x.Name,y.Name));

list.Sort((x,y)=>y.Age.CompareTo(x.Age)); // desc
list.Sort((x,y)=>x.Age.CompareTo(y.Age)); // asc

Note the second is descending, by swapping x/y in the compare.

Sign up to request clarification or add additional context in comments.

Comments

11

If you're using List<T> and you want to sort the list in place, then the Sort function provides an overload that accepts a Comparison<T>. You can use this to provide different comparisons for a list.

For example, to sort on Age:

list.Sort((x, y) => x.Age.CompareTo(y.Age));

To sort on Name:

list.Sort((x, y) => string.Compare(x.Name, y.Name));

To sort in descending order, simply reverse the parameters.

Alternatively, you could use LINQ to create various queries against your list that provide the results in whatever order you like, but this won't have any effect upon the underlying list (whether that's bad or good is up to you):

var byAge = list.OrderBy(x => x.Age);
var byName = list.OrderBy(x => x.Name);

To sort in descending order, use OrderByDescending in place of OrderBy.

2 Comments

Just an additional note: Sort differs from OrderBy because is not-stable
@digEmAll: That's correct; Enumerable.OrderBy is stable, Array.Sort (which is what List<T>.Sort uses) is unstable, since it's QuickSort.
5

You can also just use LINQ to handle this:

var sortedByAge = myList.OrderBy(i => i.Age);
var sortedByName = myList.OrderBy(i => i.Name);

If you want to handle sorting in place, you can use List<T>.Sort(Comparison<T>):

// Sort by Age
myList.Sort( (l, r) => l.Age.CompareTo(r.Age) );
// Sort by Name
myList.Sort( (l, r) => l.Name.CompareTo(r.Name) );

5 Comments

This is increasing order? and <= would be decreasing?
@Rofl, no, that's an operator that has nothing to do with ordering. These LINQ methods will be ascending. To go descending, utilize OrderByDescending.
If using this method, you may also need to tack ".ToList()" at the end, to get an actual list back, rather than an IEnumerable.
No, "=>" is the lamdba operator. Calling "Reverse" would do it.
@Roflcoptr: No - => allows you to define a lambda, which is a short, concise way to make a delegate.
2

You can sort your objects data with linq

something like this

var query = from cust in customers
            orderby cust.Age ascending
            select cust;

1 Comment

Eliminate the where portion for the purpose of this example. For one, if you're already limiting the age to a single value, ordering on age isn't going to do anything. ;)
1

You can also use

list.OrderByDescending(a => a.Age);

or

list.OrderByAscending(a => a.Age);

1 Comment

Ok, I see you can if you use LINQ.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.