2016-09-19 153 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,因爲可能會有多個「頂」,「中」或「底」產品。

此外,如果描述包含在同一個句子,「頂」和「中」「頂」和「底部」,它會不工作等。

相關問題