LINQ selective ordering, partial ordering

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 the elements with "Order> -1" are above the list, sorted in ascending order, and the rest of the elements with "Order == -1" will execute them.

Is there a more elegant way to do this than using Conact () + Where () clauses:

var orderedItems = items.Where(x => x.Order > -1).OrderBy(x => x.Order)
                   .Conact(items.Where(x => x.Order == -1);

So, after sorting, this list will look like this:

var items = new {
    new { Order = 0 },
    new { Order = 1 },
    new { Order = 2 },
    new { Order = 3 },
    new { Order = -1 },
    new { Order = -1 }
};

Also, the "items" list in a real scenario is already a complex IQueryable object. That’s why I’m trying to find the most optimal way to do such selective ordering.

+5
source share
6

- :

items.OrderBy(x.Order => x.Order == -1).ThenBy(x.Order => x.Order);
+7

, , , -1 , . , . . , false -1 ( ) true ( ). , . :

var nums = new int[] { -1, 4, 2, 3, -1, 4, 7 };
var q = from n in nums
        orderby n != -1, n descending
        select n;

, n != -1 false, , n descending, :

-1, -1, 7, 4, 4, 3, 2

, , - .

+6

, -1 , .

, , , , , , , . , -, , , .

+3
OrderBy(x => x.Order < 0 ? int.MaxValue : x.Order)

OrderBy(x => x.Order < 0 ? (long)int.MaxValue - x.Order : (long)x.Order)
+1

Also, the custom mapper is here if you want the first to be displayed first, and the rest to be descending , but for some reason I find it more elegant :) Notice what it did for ints

class Comparer : IComparer<int>
{
  public int Compare(int x, int y)
  {
    if (x == -1 || y == -1) return x - y;
    return y - x;
  }
}
+1
source

Use a custom mapper to determine the desired order.

public class MyComparer : IComparer<int>
{
    public int Compare(int a, int b)
    {
        if ((a < 0) && (b >= 0))
        {
            return 1;
        }
        if ((a >= 0) && (b < 0))
        {
            return -1;
        }
        return int.Compare(a, b);
    }
}

Then you could do:

var orderedItems = items.OrderBy(x => x.Order, new MyComparer());
0
source

All Articles