2016-09-19 107 views
-1

我已经product类具有Description性且具有3 product对象:基于某些属性对类对象进行分组和排序?

Product product1 = new Product("This is bottom product"); 
Product product2 = new Product("This is top product"); 
Product product3 = new Product("This is medium product"); 

List<Product> lst = new List<Product>(); 
lst.Add(product1); 
lst.Add(product2); 
lst.Add(product3); 

我想,让所有productstopdescription亮起顶部和productdescription作为bottom重新安排这些对象来在底部。

var res = lst.Where(p => p.Desription == "This is top product") 
         .Concat(lst.Where(p => p.Desription == "This is medium product")) 
         .Concat(lst.Where(p => p.Desription == "This is bottom product")).ToList(); 

我已经编码上述查询来实现此目的。这会返回正确的结果。但我不确定这是否是解决此问题最有效的方法?

有人可以提出任何替代/性能方面更好的方法吗?

注:我已经简化了这里的问题。否则产品有更多的对象和属性。

+2

如果你有100种产品? – AVK

+0

我的逻辑仍然有效,但我认为它会很慢。 – maverick

+4

彻底改变这个问题是个不好的形式(又名变色龙问题)。你的编辑几乎使每个人的答案无效,不是因为他们错了,而是因为你从根本上改变了问题。 – Igor

回答

2

编辑:

比比较器(快)更好的解决方案:

public enum ProductType 
    { 
     Bottom=0, 
     Medium, 
     Top, 
    } 

    public class Product 
    { 
     public ProductType Type { get; set; } 
     //the rest of properties here 
    } 

var list = new List<Product>(); 
var orderedList = list.OrderBy(x => (int)x.Type).ToList(); 

如果你不希望任何添加到现有的类,也许包裹或延伸?

+0

@FirstStep在这里,您在 – MistyK

+0

编辑该问题。 – maverick

+0

不错的解决方案,+1 –

0

使用辅助Dictionary

Dictionary<string, int> myDic = new Dictionary<string, int> 
{ 
    {"top", 1}, 
    {"medium", 2}, 
    {"bottom", 3} 
}; 
var res = lst.OrderBy(c => myDic[c.Desription.Split(' ')[2]]); 
+0

编辑问题。 – maverick

0

您可以尝试以下选项:

选项1:(无需中间结构/处理)

IEnumerable<Product> finalResult = lst.GroupBy(p => p.Description) 
             .OrderByDescending(g => g.Key) 
             .SelectMany(g => g.Select(p => p)); 

选项2 :(创建中间结构)

  • 创建一个列表来保存中间结果:

    var intermediateResult = new List<IGrouping<string,Product>>(); 
    
  • 集团通过说明

    var groupedList = lst.GroupBy(p => p.Desription) 
    
  • 添加相关组件到中间列表

    intermediateResult.AddRange(groupedList.Where(g => g.Key == "Top"); 
    intermediateResult.AddRange(groupedList.Where(g => g.Key == "Medium"); 
    intermediateResult.AddRange(groupedList.Where(g => g.Key == "Bottom"); 
    
  • 选择通过扁平化列表

    IEnumerable<Product> finalResult = intermediateResult.SelectMany(g => g.Select(p => p)); 
    
+0

不需要中间名单。 –

+0

@Ivan Stoev同意,尽管我必须使用'OrderBy',并且不确定OP期望什么样的字典顺序,因为这仅仅是一个例子,实际的数据可能不同 –

1

鉴于这在你的问题最终结果:

var res = lst.Where(p => p.Desription == "This is top product") 
         .Concat(lst.Where(p => p.Desription == "This is medium product")) 
         .Concat(lst.Where(p => p.Desription == "This is bottom product")).ToList(); 

我相信你所寻找的是这样的:

var res = lst.OrderBy(p => p.Desription); 

我d想指出你的“描述”变量是拼写错误的。

0

尝试这样的事情,如果你知道每个描述将仅包含具体措辞“顶”,“底”,“中”和那些只有一个

List<Product> res = new List<Product>(); 
for (int i = 0; i < lst.Count(); i++) 
{ 
    res.AddRange(lst.Where(p => p.Desription.Contains("top").ToList()); 
    res.AddRange(lst.Where(p => p.Desription.Contains("medium").ToList()); 
    res.AddRange(lst.Where(p => p.Desription.Contains("bottom").ToList()); 
} 

我用AddRange代替Add,因为可能会有多个“顶”,“中”或“底”产品。

此外,如果描述包含在同一个句子,“顶”和“中”“顶”和“底部”,它会不工作等。

相关问题