2011-08-18 36 views
0

我有一個數組,用於存儲我想按列表排序的順序。跨多行代碼進行多種排序?

SortOrderArray: "Color", "Volume", "Weight" 

所以我要訂購按顏色,體積,重量,然後

MyList.OrderBy(a=>a.Color).ThenBy(a=>a.Volume).ThenBy(a=>a.Weight).ToList(); 

我的列表中,這樣就不錯了。現在,我希望能寫,做基於中將sortOrder陣列我發這個排序的函數:

public List<row> GetSortedList(List<row> list, string[] sortOrder){ 
    ??? 
} 

我無法弄清楚如何做到這一點無需編寫LINQ查詢的每個組合sortOrders(27個不同的查詢似乎是完成這個任務的最糟糕的方式,並且我犯了一個很小的錯誤的可能性很高)。我想是能夠根據每個3種選方法來只寫重新排序列表3個LINQ查詢,像這樣:

switch(sortOrder[0]){ 
    Sort by the first sort method 
} 
switch(sortOrder[1]){ 
    Sort by the second sort method 
} 
switch(sortOrder[2]){ 
    Sort by the third sort method 
} 

但如果我嘗試做了上面的代碼,它只是訴諸它的每個時間,而不是在上面的分類之後進行分類。希望這是明確的,任何幫助將不勝感激。

回答

2

兩件事。您需要執行「穩定排序」的排序方法 - 它使用相同的鍵保持項目的現有順序。然後,您需要按照排序標準的相反順序調用它,以便主要排序是最後一個排序條件。

+0

這是一個聰明的解決方案,你知道Linq的訂單是否是「穩定的」?另外,「穩定排序」的正確術語是什麼(或者就是這樣) – sooprise

+1

看起來'OrderBy'是穩定的:參見[這個問題](http://stackoverflow.com/questions/148074/is-的排序算法使用的逐網陣列排序法-A-穩定算法)。 [[穩定排序]](http://en.wikipedia.org/wiki/Sorting_algorithm#Stability)是常用術語。 – AShelly

0

我想,你沒有使用訂單子句的返回值。

public List<row> GetSortedList(List<row> list, string[] sortOrder) 
{ 
    IOrderedEnumerable<row> result = null; 

    bool first = true; 

    foreach(sortClause in sortOrder) 
    { 
     switch sortClause 
     { 
      case "Color": 
       if(first) 
        result = list.OrderBy(x => x.Color); 
       else 
        result = result.ThenBy(x => x.Color); 
       break; 
      // the other cases 
     } 
     first = false; 
    }  

    return result.ToList(); 
} 

就是這樣的。

+0

看起來我只能放一個.ThenBy後.OrderBy,這代碼不能爲我工作不幸... – sooprise

+0

@sooprise:然後你在某處引入了一個錯誤。這工作。 「first」的全部意義在於,你首先需要一個OrderBy,然後才能使用ThenBy。請使用您使用的確切代碼更新您的問題。 –

+0

我有和你一樣的代碼,但是我使用的是for而不是foreach,並且檢查是否== 0而不是如果first == true。 – sooprise

0

使用Dynamic LINQ,你可以這樣做:

public List<row> GetSortedList(List<row> list, string[] sortOrder) 
{ 
    // argument-validation, including testing that 
    // sort-order has at least 1 item. 

    return sortOrder.Skip(1) 
        .Aggregate(list.AsQueryable().OrderBy(sortOrder.First()), 
           (query, nextSortTerm) => query.ThenBy(nextSortTerm)) 
        .ToList();  
} 

本質:OrderBy第一個排序來看,ThenBy剩餘。

編輯:添加一個AsQueryable呼籲作出IEnumerable<T>

+0

這看起來很酷,但是我認爲'sortorder'的第一個元素是一個字符串,轉換爲'Func '(即KeySelector)? – Smudge202

+0

@ Smudge202:這就是Dynamic LINQ所要處理的。 – Ani