LINQ自定义排序

我想要一个字母排序,但有一个例外。
有一个名为“公共”的组和一个我想要的ID =“0”的组。
(宁可使用ID = 0)
之后,按名称对其余部分进行排序。
这不会首先返回公众。

public IEnumerable GroupAuthoritysSorted { get { return GroupAuthoritys.OrderBy(x => x.Group.Name); } } 

我想要的是:

 return GroupAuthoritys.Where(x => x.ID == 0) UNION GroupAuthoritys.Where(x => x.ID > 0).OrderBy(x => x.Group.Name); 

GroupAuthority具有公共属性Group和Group具有公共属性ID和名称。

我基本上使用了接受的答案

 using System.ComponentModel; namespace SortCustom { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); TestSort(); } private void TestSort() { List LCS = new List(); LCS.Add(new CustomSort(5, "sss")); LCS.Add(new CustomSort(6, "xxx")); LCS.Add(new CustomSort(4, "xxx")); LCS.Add(new CustomSort(3, "aaa")); LCS.Add(new CustomSort(7, "bbb")); LCS.Add(new CustomSort(0, "pub")); LCS.Add(new CustomSort(2, "eee")); LCS.Add(new CustomSort(3, "www")); foreach (CustomSort cs in LCS) System.Diagnostics.Debug.WriteLine(cs.Name); LCS.Sort(); foreach (CustomSort cs in LCS) System.Diagnostics.Debug.WriteLine(cs.Name); } } public class CustomSort : Object, INotifyPropertyChanged, IComparable { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(PropertyChangedEventArgs e) { if (PropertyChanged != null) PropertyChanged(this, e); } private Int16 id; private string name; public Int16 ID { get { return id; } } public String Name { get { return name; } } public int CompareTo(CustomSort obj) { if (this.ID == 0) return -1; if (obj == null) return 1; if (obj is CustomSort) { CustomSort comp = (CustomSort)obj; if (comp.ID == 0) return 1; return string.Compare(this.Name, comp.Name, true); } else { return 1; } } public override bool Equals(Object obj) { // Check for null values and compare run-time types. if (obj == null) return false; if (!(obj is CustomSort)) return false; CustomSort comp = (CustomSort)obj; return (comp.ID == this.ID); } public override int GetHashCode() { return (Int32)ID; } public CustomSort(Int16 ID, String Name) { id = ID; name = Name; } } } 

您需要使用比较函数,它们是来自您的类型的两个实例的函数返回一个整数,如果两者都是等于则返回0,如果第一个小于第二个则返回负值,如果第一个小于第二个则返回正值第二。

MSDN有一个很好的表比文本更容易理解(StackOverflow在2014年仍然不支持表)

IComparer

大多数排序方法都接受IComparer类型的自定义比较器实现,您应该创建一个封装Group的自定义规则:

 class GroupComparer : IComparer { public int Compare(Group a, Group b) { if (a != null && b != null && (a.Id == 0 || b.Id == 0)) { if (a.Id == b.Id) { // Mandatory as some sort algorithms require Compare(a, b) and Compare(b, a) to be consitent return 0; } return a.Id == 0 ? -1 : 1; } if (a == null || b == null) { if (ReferenceEquals(a, b)) { return 0; } return a == null ? -1 : 1; } return Comparer.Default.Compare(a.Name, b.Name); } } 

用法:

 items.OrderBy(_ => _, new GroupAuthorityComparer()); 

IComparable

如果它是比较Group实例的唯一方法,那么您应该使它实现IComparable这样如果有人想要对您的类进行排序,则不需要任何附加代码:

 class Group : IComparable { ... public int CompareTo(Group b) { if (b != null && (Id == 0 || b.Id == 0)) { if (Id == b.Id) { // Mandatory as some sort algorithms require Compare(a, b) and Compare(b, a) to be consitent return 0; } return Id == 0 ? -1 : 1; } return Comparer.Default.Compare(Name, b.Name); } } 

用法:

 items.OrderBy(_ => _.Group); 

在这种方式或其他方式之间的选择应该取决于使用此特定比较器的位置:它是此类项目的主要排序还是仅在一个特定情况下应使用的排序,例如仅在某些管理视图中。

您甚至可以升级并提供IComparable实现(一旦Group实现IComparable就很容易):

 class GroupAuthority : IComparable { ... public int CompareTo(GroupAuthority b) { return Comparer.Default.Compare(Group, b.Group); } } 

用法:

 items.OrderBy(_ => _); 

最后一个的优点是它将自动使用,因此代码如: GroupAuthoritys.ToList().Sort()将开箱即用。

你可以尝试这样的事情

 list.Sort((x, y) => { if (x.Id == 0) { return -1; } if (y.Id == 0) { return 1; } return x.Group.Name.CompareTo(y.Group.Name); }); 

列表是List

此方法利用List使用Comparison委托提供的自定义排序选项。

基本上这个方法的作用是,它只是在Id时添加特殊条件进行比较,如果它为零,它将返回一个值,表示对象较小,使对象进入列表的顶部。 如果不是,它将使用其Group.Name属性按升序对对象进行排序。

  public IEnumerable GroupAuthoritysSorted { get { return GroupAuthoritys.OrderBy(x => x.Group.ID == 0) .ThenBy(x => x.Group.Name); } }