如何合并两个排序函数?

问题描述:

我使用下面的类由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

如果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

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

我用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); 

也就是说,把它在“错误”的元组。但我还没有测试过这个部分。