排序自定义对象列表
本文关键字:列表 对象 自定义 排序 | 更新日期: 2023-09-27 17:52:45
我有一个包含List<>
的对象,它来自一个具有String
属性的类,我想使用以下规则进行排序:
- 列表中所有"代码"为
X5
的对象都应该放在列表的顶部。 - 列表中"代码"为
G2
的所有对象都在X5
对象之后。 - 列表中所有"代码"为
H3
的对象都在G2
对象之后。 - 所有其他对象应在列表的末尾,按"代码"的字母顺序排序。
我尝试了一些代码,但一直抛出这个异常:
系统。无法排序,因为IComparer.Compare()方法返回不一致的结果。一个值不等于其本身,或者一个值与另一个值反复比较产生不同的结果。IComparer:"。
代码尝试:
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
}
}
之后我想创建一个列表"myObject"并排序:
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();
列表将按照以下顺序排列:
- 山姆
- 詹妮弗 杰克汤姆
如果有必要实现IComparable
,您可以使用上述答案。但是你可以就地完成。
objects.OrderBy(
o => o.code == "X5" ? 1 : o.code == "G2" ? 2 : o.code == "H3" ? 3 : 4);
如果你想在组中排序(即G2
),你也可以添加ThenBy
您要做的是保持"特殊代码"到它们的相对权重的映射(确定它们之间的排序顺序)。然后,当比较对象时:
- 如果两个代码都是"特殊的",比较结果是比较它们的权重
- 如果只有一个是特殊的,那么拥有它的对象优先出现("is smaller")
- 如果无特殊,则比较结果为
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);
}
当然,代码需要一些改进(没有null检查,它可能是一个好主意,有一个单独的比较器,而不是硬编码一个静态映射到对象类,属性名不应该全是小写的),但思想将始终是相同的
按照指定的顺序将代码存储在数组中。然后可以先对数组进行排序。索引对象代码值。
int result;
result = Array.IndexOf(codes, this.code).CompareTo(Array.IndexOf(codes, other.code));
if (result == 0)
{
result = // Compare next property.
}
// etc.
return result;
请注意,这不是一个完整的解决方案,而只是与优先于其他代码的代码相关。首先,您必须确保这两个代码都在数组中,并处理它们不是分开的情况。