2012-08-11 37 views
2

我的产品列表以及它们的类别编号,如: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? 感谢

+0

通过使用'orderby'? http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – 2012-08-11 20:09:44

+0

您首先需要在“数学”中定义您的订单。 1,8,9,7,10不是正常的顺序。您可以添加索引,如{1,1},{8,2},{9,3},{7,4},{10,5}并按索引排序。 – 2012-08-11 20:11:42

+0

如果OP错误地输入了他正在寻找的结果并且它就像一个简单的数字“orderBy”一样简单,那么这真的很有趣......仍然是非常有趣且有趣的解决方案,但有趣。 – 2012-08-12 01:12:57

回答

0

您可以使用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现在包含在产品列表inordered序列。你可以通过它像枚举:

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

编辑:误解了答案。将更新答案。

5

如果你的类别ID在列表中,您可以订购这样的:

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只有工作对象,所以你需要把从数据库无序的所有数据。

+2

这会起作用,但是如果'list'非常大,那将会很糟糕。 – 2012-08-11 20:28:18

+1

你说得对。你的解决方案更好。 – 2012-08-11 20:33:05

+0

虽然取决于。低于特定数量时,您的工作就会进行 - 无需浪费时间来设置字典,迭代列表的常量因子比查找字典要低,因此对于小型集合,“IndexOf”比“TryGetValue”快。我认为这两种方法的价值都没有价值。 – 2012-08-11 21:03:30

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(纳米) 。

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

将第二个最后一个类别放在'products'中,它首先出现在结果中,这是不正确的。 – 2012-08-11 21:04:44