2013-03-19 117 views
2

我使用下面的類由type成員對列表進行排序:如何合併兩個排序函數?

public class CameraSortByType : IComparer<Camera> 
{ 
    private bool asc; 

    public CameraSortByType(bool a) 
    { 
     this.asc = a; 
    } 

    public int Compare(Camera x, Camera y) 
    { 
     if (x.type > y.type) 
      return asc? -1 : 1; 
     if (x.type < y.type) 
      return asc? 1 : -1; 
     else 
      return 0; 
    } 
} 

我也name排序相同的列表:

myList.Sort((s1, s2) => s2.name.CompareTo(s1.name)); 

我怎樣才能納入排序的名字進入按類型排序類?所以當我按類型排序時,它也按名稱排序?

更新:LINQ的版本

var primarySortResult = primarySort ? CameraStorage.CameraList.OrderBy(x => x.type) : CameraStorage.CameraList.OrderByDescending(x => x.type); 
var secondarySortResult = secondarySort ? primarySortResult.ThenBy(x => x.name) : primarySortResult.ThenByDescending(x => x.name); 
CameraStorage.CameraList = secondarySortResult.ToList(); 
+0

是LINQ的一個選擇嗎? – 2013-03-19 11:52:33

+0

好吧,如果它可以在我的'CameraSortByType'裏面,那就沒問題。 – Pablo 2013-03-19 11:53:32

+0

不,我問了選項list.OrderBy(x => x.type).ThenBy(x => x.name)' – 2013-03-19 11:54:49

回答

1

如果LINQ是你可以用下面的運營商建立有序序列的一個選項:

樣品:

var orderedList = myList.OrderBy(x => x.type) 
         .ThenByDescending(x => x.name) 
         .ToList(); 

如果您需要訂購基於一些條件:

var result = ascendingByType ? myList.OrderBy(x => x.type) : 
           myList.OrderByDescending(x => x.type); 

if (orderByNameRequired) 
{ 
    result = ascendingByName ? result.ThenBy(x => x.name) : 
           result.ThenByDescending(x => x.name); 
} 

orderedList = result.ToList(); 

還可以考慮使用Dynamic Linq


另外這裏的排序上兩個屬性比較器的實現(也考慮在此空值處理):

public class CameraComparer : IComparer<Camera> 
{ 
    private SortDirection typeSortDirection; 
    private SortDirection nameSortDirection; 

    public CameraComparer(SortDirection typeSortDirection, 
          SortDirection nameSortDirection) 
    { 
     this.typeSortDirection = typeSortDirection; 
     this.nameSortDirection = nameSortDirection; 
    } 

    public int Compare(Camera x, Camera y) 
    { 
     if (x.Type == y.Type) 
      return x.Name.CompareTo(y.Name) * 
      (nameSortDirection == SortDirection.Ascending ? 1 : -1); 

     return x.Type.CompareTo(y.Type) * 
      (typeSortDirection == SortDirection.Ascending ? 1 : -1); 
    } 
} 

public enum SortDirection 
{ 
    Ascending, 
    Descending 
} 

用法:

myList.Sort(new CameraComparer(SortDirection.Ascending, SortDirection.Descending)); 
+0

什麼是最好的方法來整合我的'asc'布爾值到這個從Asc切換到Desc?任何捷徑或我將使用'if'語句? – Pablo 2013-03-19 12:16:00

+1

對不起,我沒有看到您的更新。謝謝,現在會檢查這個。 – Pablo 2013-03-19 12:16:40

+1

@Pablo我使用比較器實現更新了答案 – 2013-03-19 12:27:41

1
public int Compare(Camera x, Camera y) 
{ 
    if (x.type > y.type) 
     return asc ? -1 : 1; 

    if (x.type < y.type) 
     return asc ? 1 : -1; 

    if (x.name.CompareTo(y.name) > 0) 
     return asc ? -1 : 1; 

    if (x.name.CompareTo(y.name) < 0) 
     return asc ? 1 : -1; 

    return 0; 
} 
+0

名稱是'string'類型。我應該使用'name.CompareTo()'? – Pablo 2013-03-19 11:57:39

+0

可以做,但不知道'CompareTo'如何與您的自定義排序方向一起工作。 – paul 2013-03-19 11:58:24

+0

@Pablo沒有必要,但它會是'return x.name.CompareTo(y.name)'而不是最後兩個'if's。 – 2013-03-19 12:05:43

1

我用Tuples的情況是這樣的:

public int Compare(Camera x, Camera y) { 
    var xx = Tuple.Create(x.name, x.type); 
    var yy = Tuple.Create(y.name, y.type); 
    return xx.CompareTo(yy); 
} 

也就是說,假設你想所有屬性以相同的順序進行比較。如果不是這樣,我想可能扭轉,其中一個屬性(例如name)是通過做類似考慮的順序:

var xx = Tuple.Create(y.name, x.type); 
var yy = Tuple.Create(x.name, y.type); 

也就是說,把它在「錯誤」的元組。但我還沒有測試過這個部分。