Порядок LINQ по числовой последовательности

У меня есть список продуктов с их идентификатором категории, например:

ID      CategoryID     Product Name
1       1              Product 1
2       1              Product 2
3       7              Product 3
4       8              Product 4
5       9              Product 5
6       10             Product 6

Я хочу взять этот список и заказать по списку categoryID, например: 1, 8, 9, а остальное, поэтому я получаю:

ID     CategoryID     Product Name
1      1              Product 1
2      1              Product 2
4      8              Product 4
5      9              Product 5
3      7              Product 3
6      10             Product 6

Есть ли какой-либо путь к этому с linq? Благодаря

+2
источник поделиться
5 ответов

Если ваши идентификаторы категорий указаны в списке, вы можете сделать следующее:

var list = new List<int>() { 1, 8, 9, 7, 10, ... };

var productsOrdered = from p in products
    let index = list.IndexOf(p.CategoryID)
    order by (index < 0 ? int.MaxValue : index) // in case it is not in the list
    select p;

Этот запрос будет работать только с Linq to Objects, поэтому вам нужно будет удалить все данные из вашей базы данных.

+5
источник

Предполагая, что 1,8,9 в списке, мы назовем orderList, тогда, пока мы можем продолжать искать позицию в списке каждый раз, мы быстрее создадим словарь для поиска это быстро.

var orderDict = orderList.Select((o, index) => new {ID = o, Order=index}).ToDictionary(oi => oi.ID, oi => oi.Order);
int orderHolder;
var orderedProducts = products.OrderBy(p => orderDict.TryGetValue(p.CategoryID, out orderHolder) ? orderHolder : int.MaxValue);

Нам не нужно сначала настраивать orderDict, но он делает логику проще, чем сканирование через список каждый раз, а также быстрее: O (n + m), а не O (nm).

+5
источник

Вы можете использовать Enumerable.OrderBy:

var catIDs = new[] { 1, 8, 9 };
var ordered = products
    .OrderByDescending(p => catIDs.Contains(p.CategoryID))
    .ThenBy(p => p.CategoryID);

Изменить: Здесь демо: http://ideone.com/O462C

0
источник
var query = from p in productsList
            orderby p.CategoryID descending
            select new {ID = p.ID, CID = p.CategoryID, PName = p.ProductName};

query теперь содержит список продуктов с порядком. Вы можете перечислить его, как:

foreach(Product prod in query)
   Console.WriteLine(prod.CID);

Изменить: неправильно понял ответ. Будет обновлен ответ.

0
источник

Если вы знаете все, что хотите сортировать в верхней части списка, попробуйте следующее:

var products = new List<Product>();

products.Add(new Product { ID = 1, CategoryID = 1, ProductName = "1" });
products.Add(new Product { ID = 2, CategoryID = 1, ProductName = "2" });
products.Add(new Product { ID = 3, CategoryID = 7, ProductName = "3" });
products.Add(new Product { ID = 4, CategoryID = 8, ProductName = "4" });
products.Add(new Product { ID = 5, CategoryID = 9, ProductName = "5" });
products.Add(new Product { ID = 6, CategoryID = 10, ProductName = "6" });

products
    .OrderByDescending(p => p.CategoryID == 1 || p.CategoryID == 8 || p.CategoryID == 9)
    .ThenBy(p => p.CategoryID);

Производит это (из LinqPad):

ID CategoryID ProductName 
1  1          1 
2  1          2 
4  8          4 
5  9          5 
3  7          3 
6  10         6 
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос