3

Is it possible to use LINQ OrderBy like so:

.OrderBy(x=>(x.SourceID == 3), (x.SourceID == 2), (x=>x.SourceID == 4), (x.SourceID == 1)).ToList();

So it'll order them by 3, 2, 4, 1 ?

CallumVass
  • 10,584
  • 24
  • 75
  • 146
  • I never knew `OrderBy` had an extension like that. – Bastardo Jan 27 '12 at 13:06
  • It doesn't but is there something similar to that which I can use to explicitly order a list of a complex datatype? – CallumVass Jan 27 '12 at 13:08
  • I really don't have any idea what explicitly means in this situation, my lack of knowledge sorry but is `ThenBy` what you are looking for?Check http://stackoverflow.com/a/298741/647884. What you want to do is basically "Multiple Order By in LINQ", is it not? Check http://stackoverflow.com/questions/298725/multiple-order-by-in-linq. – Bastardo Jan 27 '12 at 13:10
  • So, Orderby(x=>x.SourceID == 3).ThenBy(x=>x.SourceID == 2).ThenBy(x=>X.SourceID == 4)...? – CallumVass Jan 27 '12 at 13:12

2 Answers2

7

No, that is not a valid lambda expression. What you could do instead is something like;

var sortOrder = new List<int> {3, 2, 4, 1};
var result = bop.OrderBy(x=> sortOrder.IndexOf(x.SourceID)).ToList();

If you want to extend this to doing special things with unknowns (they end up first now), you can just make a method that makes the determination of the sort order and use that instead.

Joachim Isaksson
  • 163,843
  • 22
  • 249
  • 272
  • When I try this I get: LINQ to Entities does not recognize the method 'Int32 IndexOf(Int32)' method, and this method cannot be translated into a store expression. – CallumVass Jan 27 '12 at 14:03
  • Ah, then your Linq provider (Linq2NHibernate? Linq2Entities?) doesn't support IndexOf. What is the underlying Linq provider? – Joachim Isaksson Jan 27 '12 at 14:07
  • Well, does your program use NHibernate or Entity Framework (EF)? Either way, if that's the only thing you're getting from the database without much additional complexity, you can always fetch it to memory before sorting by doing bop.ToList().OrderBy(... which should work no matter the provider. – Joachim Isaksson Jan 27 '12 at 14:13
  • So I would do bop.ToList().OrderBy(x=> sortOrder.IndexOf(x.SourceID)); ? – CallumVass Jan 27 '12 at 14:18
2

Taking Joachim Isaksson's answer above, this could be wrapped in an extension method:

public static class ListExtensions
{
    public static List<Source> SortByCustomOrder(this List<Source> list, List<int> sortOrder)
    {
        return list.OrderBy(x => sortOrder.IndexOf(x.SourceId)).ToList();
    }
}

replacing Source with your Class and x.SourceId with your property

Usage:

// the sort order
var sortOrder = new List<int> { 3, 2, 4, 1, 6, 5 };
var results = sources.SortByCustomOrder(sortOrder);
mjbates7
  • 614
  • 1
  • 6
  • 15