C# 对自定义对象列表进行排序

C# 对自定义对象列表进行排序,c#,sorting,C#,Sorting,我有一个列表,其中包含一个类中的对象,该类有一个字符串属性,我想使用以下规则对该属性进行排序: 列表中“代码”为X5的所有对象都应位于列表顶部 列表中“代码”为G2的所有对象将位于X5对象之后 列表中“代码”为H3的所有对象将位于G2对象之后 所有其他对象应位于列表的末尾,按“代码”字母顺序排序 我尝试了一些代码,但一直抛出此异常: public class myObject: IComparable<myObject> { int id { get; set; } st

我有一个
列表
,其中包含一个类中的对象,该类有一个
字符串
属性,我想使用以下规则对该属性进行排序:

  • 列表中“代码”为
    X5
    的所有对象都应位于列表顶部
  • 列表中“代码”为
    G2
    的所有对象将位于
    X5
    对象之后
  • 列表中“代码”为
    H3
    的所有对象将位于
    G2
    对象之后
  • 所有其他对象应位于列表的末尾,按“代码”字母顺序排序
  • 我尝试了一些代码,但一直抛出此异常:

    public class myObject: IComparable<myObject>
    {
       int id { get; set; }
       string name { get; set; }
       string code { get; set; }
    
       public myObject()
       {
       }
    
       public int CompareTo(myObject other)
       {
           //I don't know how to write the sort logic
       }
    }
    
    List<myObject> objects = new List<myObject>();
    objects.Add(new MyObject() { id = 0, name = "JENNIFER"; code = "G2"; });
    objects.Add(new MyObject() { id = 1, name = "TOM"; code = "H3"; });
    objects.Add(new MyObject() { id = 2, name = "JACK"; code = "G2"; });
    objects.Add(new MyObject() { id = 3, name = "SAM"; code = "X5"; });
    objects.Sort();
    
    System.ArgumentException:无法排序,因为IComparer.Compare()方法返回不一致的结果。一个值与自身比较不相等,或者一个值与另一个值重复比较会产生不同的结果。我比较:''

    代码尝试:

    public class myObject: IComparable<myObject>
    {
       int id { get; set; }
       string name { get; set; }
       string code { get; set; }
    
       public myObject()
       {
       }
    
       public int CompareTo(myObject other)
       {
           //I don't know how to write the sort logic
       }
    }
    
    List<myObject> objects = new List<myObject>();
    objects.Add(new MyObject() { id = 0, name = "JENNIFER"; code = "G2"; });
    objects.Add(new MyObject() { id = 1, name = "TOM"; code = "H3"; });
    objects.Add(new MyObject() { id = 2, name = "JACK"; code = "G2"; });
    objects.Add(new MyObject() { id = 3, name = "SAM"; code = "X5"; });
    objects.Sort();
    
    公共类myObject:IComparable
    {
    int id{get;set;}
    字符串名称{get;set;}
    字符串代码{get;set;}
    公共对象()
    {
    }
    公共内部比较(myObject其他)
    {
    //我不知道如何编写排序逻辑
    }
    }
    
    稍后我想创建一个“myObject”列表并对其排序:

    public class myObject: IComparable<myObject>
    {
       int id { get; set; }
       string name { get; set; }
       string code { get; set; }
    
       public myObject()
       {
       }
    
       public int CompareTo(myObject other)
       {
           //I don't know how to write the sort logic
       }
    }
    
    List<myObject> objects = new List<myObject>();
    objects.Add(new MyObject() { id = 0, name = "JENNIFER"; code = "G2"; });
    objects.Add(new MyObject() { id = 1, name = "TOM"; code = "H3"; });
    objects.Add(new MyObject() { id = 2, name = "JACK"; code = "G2"; });
    objects.Add(new MyObject() { id = 3, name = "SAM"; code = "X5"; });
    objects.Sort();
    
    List objects=newlist();
    Add(newmyObject(){id=0,name=“JENNIFER”;code=“G2”});
    Add(newmyobject(){id=1,name=“TOM”;code=“H3”});
    Add(newmyobject(){id=2,name=“JACK”;code=“G2”});
    添加(新的MyObject(){id=3,name=“SAM”;code=“X5”});
    objects.Sort();
    
    列表的顺序如下:

    public class myObject: IComparable<myObject>
    {
       int id { get; set; }
       string name { get; set; }
       string code { get; set; }
    
       public myObject()
       {
       }
    
       public int CompareTo(myObject other)
       {
           //I don't know how to write the sort logic
       }
    }
    
    List<myObject> objects = new List<myObject>();
    objects.Add(new MyObject() { id = 0, name = "JENNIFER"; code = "G2"; });
    objects.Add(new MyObject() { id = 1, name = "TOM"; code = "H3"; });
    objects.Add(new MyObject() { id = 2, name = "JACK"; code = "G2"; });
    objects.Add(new MyObject() { id = 3, name = "SAM"; code = "X5"; });
    objects.Sort();
    
  • 萨姆
  • 珍妮弗
  • 杰克
  • 汤姆

  • 您要做的是将“特殊代码”映射到它们的相对权重(决定它们之间的排序顺序)。然后,在比较对象时:

    • 如果两个代码都是“特殊”的,则比较结果是比较它们的权重
    • 如果只有一个是特殊的,那么首先出现的对象(“较小”)
    • 如果没有特殊项,则比较结果为
      code1.CompareTo(code2)
    这将允许您在将来非常轻松地维护代码(如果您需要添加更多特殊代码或更改已有代码的权重)

    因此,代码看起来有点像这样:

    private static readonly Dictionary<string, int> weights =
    new Dictionary<string, int>()
    {
        { "X5", 1 },
        { "G2", 2 },
        { "H3", 3 }
    }
    
    public int CompareTo(myObject other)
    {
        var thisIsSpecial = weights.ContainsKey(this.code);
        var otherIsSpecial = weights.ContainsKey(other.code);
    
        if (thisIsSpecial && otherIsSpecial)
        {
            return weights[this.code] - weights [other.code];
        }
        else if (thisIsSpecial)
        {
            return -1;
        }
        else if (otherIsSpecial)
        {
            return 1;
        }
    
        return this.code.CompareTo(other.code);
    }
    
    专用静态只读字典权重=
    新字典()
    {
    {“X5”,1},
    {“G2”,2},
    {“H3”,3}
    }
    公共内部比较(myObject其他)
    {
    var thisIsSpecial=weights.ContainsKey(this.code);
    var otherIsSpecial=weights.ContainsKey(other.code);
    如果(这是特殊的&其他是特殊的)
    {
    返回权重[this.code]-权重[other.code];
    }
    否则,如果(这是特殊的)
    {
    返回-1;
    }
    其他如果(其他特殊)
    {
    返回1;
    }
    返回此.code.CompareTo(其他.code);
    }
    

    当然,代码需要一些改进(不检查null,最好使用单独的比较器,而不是将静态映射硬编码到对象类中,属性名称不应全部小写),但想法始终是一样的。

    按照指定的顺序将代码存储在数组中。然后可以首先对目标代码值的Array.indexo进行排序

    int result;
    
    result = Array.IndexOf(codes, this.code).CompareTo(Array.IndexOf(codes, other.code));
    
    if (result == 0)
    {
        result = // Compare next property.
    }
    
    // etc.
    
    return result;
    

    请注意,这不是一个完整的解决方案,只是与优先于其他代码的代码相关。您首先必须确保这两个代码都在数组中,并处理它们不单独存在的情况。

    如果有必要实现
    IComparable
    ,您可以使用上面的答案。但你可以就地完成

    objects.OrderBy(
             o => o.code == "X5" ? 1 : o.code == "G2" ? 2 : o.code == "H3" ? 3 : 4);
    

    如果您希望分组排序(即
    G2
    ),您也可以添加
    ,然后再添加

    将排序逻辑从CompareTo粘贴到methodWell,那里的排序逻辑在哪里?我以前从未编写过排序逻辑,而且我的第一次尝试非常糟糕,因此它对问题的解释没有多大帮助。这将为Jack/Jennifer提供错误的顺序-我相信,在这种情况下,应该使用名称比较来处理最后的代码比较==0,如果特定的部分很重要(问题不确定)。@ReedCopsey:是的,不确定排序的示例“恰好”是这样的,但规则已经明确说明,此时它们没有提到名称。@miniBill In place我的意思是没有实现
    IComperable
    。在排序中,In place通常意味着另一件事