Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq OrderBy Any Property

I know how to order by one property, then another property. I'm wondering if there is a linq way to order by any property (or multiple properties at the same time).

For example a list of names:

   ->Adam     Jones
   ->Dude     Lebowski
   ->Zander   Berry

Would be sorted:

   ->Adam     Jones
     Zander ->Berry
   ->Dude     Lebowski
like image 916
Josiah Ruddell Avatar asked Dec 08 '10 17:12

Josiah Ruddell


2 Answers

That's an odd one to want.

You can pass any Func<TSource, TKey> you like into OrderBy:-

names.OrderBy(x => x.FirstName.CompareTo(x.LastName) < 0
                     ? x.FirstName
                     : x.LastName);

Or if you think the inline ternary looks ugly (or if you need to reuse the sort all over the place), you can write your own IComparer:-

http://msdn.microsoft.com/en-us/library/bb549422.aspx

class PersonFirstOrLastNameComparer : IComparer<Person>
{
  public int Compare( Person x, Person y )
  {
    return GetKey( x ).CompareTo( GetKey( y ) );
  }

  private String GetKey( Person person )
  {
    if ( person.FirstName.CompareTo( person.LastName ) < 0 )
    {
      return person.FirstName;
    }
    else
    {
      return person.LastName;
    }
  }
}

and:-

names.OrderBy(x => x, new PersonFirstOrLastNameComparer());

Really though, I'd advise against it. If you find yourself sorting by the earlier of two properties on a model class, I suspect it's likely that your model class isn't up to the task.

I can't say more without knowing more about your specific application, but I'd probably advise either encapsulating that logic inside the model class (either by providing a specific property e.g. Person.SortKey or if it's a universal sort by overriding CompareTo) or creating a view model. The code snippets I posted would be a bit of an eyebrow-raiser in a code review. I think keeping the logic with the model (or ViewModel) would clarify the purpose.

like image 57
Iain Galloway Avatar answered Oct 13 '22 20:10

Iain Galloway


What about:

.OrderBy(obj => (obj.PropA < obj.PropB) ? obj.PropA : obj.PropB)
like image 35
cdhowie Avatar answered Oct 13 '22 21:10

cdhowie