ekkis ekkis - 1 year ago 70
C# Question

OrderByWithDirection when direction depends on data

In this SO article: ascending/descending in LINQ - can one change the order via parameter? a solution was presented for how to conditionally order in ascending or descending order.

what the article doesn't cover is, what if I want to make the decision based on the data in the query (which is, actually, what is most likely)?

I cannot seem to do:

source.OrderByWithDirection(o => o.MyColumnToOrderBy, o => o.SortingDirection)

would I then need to rewrite the methods? how?

- update -

by way of rationale, here is what I'm looking to accomplish:

Strike Type Price
98 Ask 101
98 Ask 100
98 Ask 99
98 Bid 95
98 Bid 96
98 Bid 97

as you can see, asks are sorted down but bids are sorted up such that the rows with the greatest difference are next to each other. so what I'd like to say is something like:

source.OrderBy(o => new { o.Strike, o.Type })
.ThenByWithDirection(o => o.Price, o => o.Type == "Ask" ? __down__ : __up__)

- update II -

a clumsy way to do this would be to issue two separate queries like this:

.Where(o => o.Type == "Ask")
.OrderBy(o => new { o.Strike, o.Type })
.ThenBy(o => o.Price)

.Where(o => o.Type == "Bid")
.OrderBy(o => new { o.Strike, o.Type })
.ThenByDescending(o => o.Price)

and concatenate them

Answer Source

I don't have your entities/objects, but can you not just do something like:

var items = from t in source
    select new { a = t, b = t.Type == "Ask" ? -t.Price : t.Price };
var sorted = from x in items
     orderby x.a.Type, x.b
     select x.a;

That is, create a new object that contains a single property by which you can perform a sort, and then use that in your ordering operations?