Let's say I have a list of objects:
var items = new {
new { Order = 0 },
new { Order = 1 },
new { Order = -1 },
new { Order = 3 },
new { Order = 2 },
new { Order = -1 }
};
I need to order it so that items with Order > -1
be on top of the list ordered by Order ascending, and remaining items with Order == -1
were following them.
Is there a more elegant way of doing this than using Conact()
and Where()
clauses:
var orderedItems = items.Where(x => x.Order > -1).OrderBy(x => x.Order)
.Conact(items.Where(x => x.Order == -1);
So that after sorting this list would look like:
var items = new {
new { Order = 0 },
new { Order = 1 },
new { Order = 2 },
new { Order = 3 },
new { Order = -1 },
new { Order = -1 }
};
Also items
list in actual scenario is already a complex IQueryable<T>
object. That's why I am trying to find the most optimal way of doing such selective ordering.
You could try this - it produces the result you expect:
items.OrderBy(x.Order => x.Order == -1).ThenBy(x.Order => x.Order);
As Mike mentioned, in your example, it would work automatically, but say we wanted to get all -1 elements first and then sort remaining elements in a descending order. This can be done using a nice trick. You can use multiple keys when ordering elements. The first key can be a Boolean value which will be false
for all -1 values (so they will be first) and true
for all other values (so they won't be reordered). The second key can be whatever you want to order the remaining elements. For example:
var nums = new int[] { -1, 4, 2, 3, -1, 4, 7 };
var q = from n in nums
orderby n != -1, n descending
select n;
It will first yield all values for which n != -1
is false
and then all elements ordered using n descending
so you'll get:
-1, -1, 7, 4, 4, 3, 2
This works in general when you need to handle some elements especially in the ordering - you just need to provide the right ordering keys.
If you order by ascending, -1 should already be at the top of the list, because it is the smallest value.
However, more generally, if you still wanted to apply different sorting to subsets of the data, I don't think there would be a more elegant way, because that's exactly what you are doing and the union is logically accurate. You're trying to pull two seperate subset of the data out, sort them differently, and then merge them together, which is one of the things what I union is to be used for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With