C# LINQ自定义排序

C# LINQ自定义排序,c#,linq,sorting,C#,Linq,Sorting,我要按字母顺序排序,只有一个例外。 我首先需要一个名为“Public”且ID为“0”的组。 (宁愿使用ID=0) 然后按名称对其余的进行排序。 这不会首先返回public public IEnumerable<GroupAuthority> GroupAuthoritysSorted { get { return GroupAuthoritys.OrderBy(x => x.Group.Name); } } GroupAuthori

我要按字母顺序排序,只有一个例外。
我首先需要一个名为“Public”且ID为“0”的组。
(宁愿使用ID=0)
然后按名称对其余的进行排序。
这不会首先返回public

public IEnumerable<GroupAuthority> GroupAuthoritysSorted 
{ 
   get 
   { 
       return GroupAuthoritys.OrderBy(x => x.Group.Name); 
   } 
}
GroupAuthority具有公共属性组,而组具有公共属性ID和名称

我基本上使用了公认的答案

using System.ComponentModel;

namespace SortCustom
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            TestSort();
        }
        private void TestSort()
        {
            List<CustomSort> LCS = new List<CustomSort>();
            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<CustomSort>
    {
        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;
        }
    }
}
使用System.ComponentModel;
名称空间SortCustom
{
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
TestSort();
}
私有void TestSort()
{
列表LCS=新列表();
LCS.Add(新客户分类(5,“sss”);
LCS.Add(新客户分类(6,“xxx”);
LCS.Add(新客户分类(4,“xxx”);
LCS.Add(新客户分类(3,“aaa”);
LCS.Add(新客户分类(7,“bbb”);
添加(新的自定义排序(0,“发布”);
LCS.Add(新客户分类(2,“eee”);
LCS.Add(新客户分类(3,www);;
foreach(LCS中的CustomSort cs)System.Diagnostics.Debug.WriteLine(cs.Name);
LCS.Sort();
foreach(LCS中的CustomSort cs)System.Diagnostics.Debug.WriteLine(cs.Name);
}
}
公共类CustomSort:Object,INotifyPropertyChanged,IComparable
{
公共事件属性更改事件处理程序属性更改;
PropertyChanged上的公共无效(PropertyChangedEventArgs e)
{
如果(PropertyChanged!=null)PropertyChanged(this,e);
}
私有Int16 id;
私有字符串名称;
public Int16 ID{get{return ID;}}
公共字符串名称{get{return Name;}}
公共整数比较(自定义排序对象)
{
如果(this.ID==0)返回-1;
if(obj==null)返回1;
if(obj为自定义排序)
{
CustomSort comp=(CustomSort)obj;
如果(comp.ID==0)返回1;
返回string.Compare(this.Name,comp.Name,true);
}
其他的
{
返回1;
}
}
公共覆盖布尔等于(对象对象对象)
{
//检查空值并比较运行时类型。
if(obj==null)返回false;
如果(!(obj为CustomSort))返回false;
CustomSort comp=(CustomSort)obj;
返回(comp.ID==this.ID);
}
公共覆盖int GetHashCode()
{
返回(Int32)ID;
}
公共自定义排序(Int16 ID,字符串名称)
{
id=id;
名称=名称;
}
}
}

您可以尝试类似的方法

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
使用
Comparison
委托提供的自定义排序选项


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

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

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

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

class GroupComparer : IComparer<Group>
{
    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<string>.Default.Compare(a.Name, b.Name);
    }
}


i可比较
如果这是比较
实例的唯一方法,那么您应该实现它,这样,如果有人想对您的类进行排序,就不需要使用传统代码:

class Group : IComparable<Group>
{
    ...

    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<string>.Default.Compare(Name, b.Name);
    }   
}
应根据使用此特定比较器的位置来选择一种方式或另一种方式:这是此类项目的主要顺序,还是仅在特定情况下(例如,仅在某些管理视图中)应使用的顺序

您甚至可以提高一个级别,提供一个
IComparable
实现(一旦组实现
IComparable
,就很容易了):

最后一个的优点是它将被自动使用,因此像:
GroupAuthoritys.ToList().Sort()
这样的代码将立即执行正确的操作。

public IEnumerable groupauthority
    public IEnumerable<GroupAuthority> GroupAuthoritysSorted 
    { 
        get 
        { 
            return GroupAuthoritys.OrderBy(x => x.Group.ID == 0)
                                  .ThenBy(x => x.Group.Name); 
        } 
    }
{ 得到 { 返回GroupAuthoritys.OrderBy(x=>x.Group.ID==0) .ThenBy(x=>x.Group.Name); } }
向我们展示
类GroupAuthority
@ClickRick GroupAuthority具有公共属性组,组具有公共属性ID和名称。请将其编辑到您的问题中。GroupAuthoritys.OrderBy(x=>x.Group.Name==“public”&&x.Group.ID==0?0:1,x.Group.Name);在纽约的电话里,我记不清确切的语法了,但这是做这件事的基本思路。这就是争取选票,我真希望我能理解它。请解释。@Blam补充了解释,抱歉耽搁了。是我离开办公室的时候了:(我没有投反对票。我将尝试并测试它。@bum谢谢,我在发帖前测试过,如果有什么让我知道的话,我会调查它。这有效+1。你为什么认为-2这个问题?
class Group : IComparable<Group>
{
    ...

    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<string>.Default.Compare(Name, b.Name);
    }   
}
items.OrderBy(_ => _.Group);
class GroupAuthority : IComparable<GroupAuthority>
{
    ...

    public int CompareTo(GroupAuthority b)
    {
        return Comparer<Group>.Default.Compare(Group, b.Group);
    }
}
items.OrderBy(_ => _);
    public IEnumerable<GroupAuthority> GroupAuthoritysSorted 
    { 
        get 
        { 
            return GroupAuthoritys.OrderBy(x => x.Group.ID == 0)
                                  .ThenBy(x => x.Group.Name); 
        } 
    }