我尝试按类型对列表中的对象进行排序,然后使用IComparable接口按名称对它们进行排序。按名称排序不是问题,但是(至少对我而言)难以按对象类型排序。我有三个类Schoen,Shirt和Broek,它们继承自抽象类Artikel。每个对象只有名称和价格属性(继承自Artikel)。
按名称排序将导致:
jan 10 (schoen)
clara 20 (broek)
denise 30 (shirt)
karel 40 (broek)
lena 50 (broek)
marie 60 (schoen)
nico 70 (shirt)
otto 80 (shirt)
pauline 90 (schoen)
我正在寻找的是这个结果:
jan 10 (schoen)
marie 60 (schoen)
pauline 90 (schoen)
clara 20 (broek)
karel 40 (broek)
lena 50 (broek)
denise 30 (shirt)
nico 70 (shirt)
otto 80 (shirt)
我不知道如何在文章类中告诉CompareTo如何做到这一点。有人能指出我正确的方向。这可能是我忽略的一些简单。
更新18-08: 用于测试的代码:
public class ArtikelTypeComparer : Comparer<Artikel>
{
private static Dictionary<string, int> nameSortOrder = new Dictionary<string, int>
{
{"schoen", 0 },
{"broek", 1 },
{"shirt", 2 },
{"unknown", int.MaxValue }
};
public override int Compare(Artikel x, Artikel y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int xOrder;
int yOrder;
if (!nameSortOrder.TryGetValue(x.GetType().Name, out xOrder))
{
xOrder = nameSortOrder["unknown"];
}
if (!nameSortOrder.TryGetValue(y.GetType().Name, out yOrder))
{
yOrder = nameSortOrder["unknown"];
}
int rslt = xOrder.CompareTo(yOrder);
if (rslt != 0)
{
return rslt;
}
// Types are the same. Compare names.
return x.Naam.CompareTo(y.Naam);
}
}
以我的形式:
private void btnSorteer_Click(object sender, EventArgs e)
{
app.artikelen.Sort(new ArtikelTypeComparer());
VerversAlleLijsten();
}
答案 0 :(得分:0)
有几种方法可以做到这一点。使用LINQ,您希望使用OrderBy
和ThenBy
。在您的情况下,您希望先按类型排序,然后按名称排序。
按类型排序需要自定义比较。我们称之为ArtikelTypeComparer
。按名称排序完全没问题。对项目进行排序并返回列表的代码是:
var sorted = MyList
.OrderBy(item => item, new ArtikelTypeComparer())
.ThenBy(item => item.Name)
.ToList();
您从ArtikelTypeComparer
类派生您的public class ArtikelTypeComparer: Comparer<Artikel>
{
private static Dictionary<string, int> NameSortOrder = new Dictionary<string, int>
{
{"schoen", 0},
{"broek", 1},
{"shirt", 2},
{"unknown", int.MaxValue}
};
public override int Compare(Artikel x, Artikel y)
{
if (x.ReferenceEquals(null) && y.ReferenceEquals(null)) return 0;
if (x.ReferenceEquals(null)) return -1;
if (y.ReferenceEquals(null)) return 1;
int xOrder;
int yOrder;
if (!nameSortOrder.TryGetValue(x.GetType().Name), out xOrder))
{
xOrder = nameSortOrder["unknown"];
}
if (!nameSortOrder.TryGetValue(y.GetType().Name), out yOrder))
{
yOrder = nameSortOrder["unknown"];
}
return xSortOrder.CompareTo(ySortOrder);
}
。因为您的类型排序不是基于名称,所以我创建了一个分配排序顺序的查找表。我添加了一个&#34;未知&#34;键入,以便如果您添加一个新类型并忘记更新此比较器,该事件不会崩溃。这些新类型将被排序到底部。
List.Sort
如果您使用public class ArtikelTypeAndNameComparer: Comparer<Artikel>
{
private static Dictionary<string, int> NameSortOrder = new Dictionary<string, int>
{
{"schoen", 0},
{"broek", 1},
{"shirt", 2},
{"unknown", int.MaxValue}
};
public override int Compare(Artikel x, Artikel y)
{
if (x.ReferenceEquals(null) && y.ReferenceEquals(null)) return 0;
if (x.ReferenceEquals(null)) return -1;
if (y.ReferenceEquals(null)) return 1;
int xOrder;
int yOrder;
if (!nameSortOrder.TryGetValue(x.GetType().Name), out xOrder))
{
xOrder = nameSortOrder["unknown"];
}
if (!nameSortOrder.TryGetValue(y.GetType().Name), out yOrder))
{
yOrder = nameSortOrder["unknown"];
}
int rslt = xSortOrder.CompareTo(ySortOrder);
if (rslt != 0)
{
return rslt;
}
// Types are the same. Compare names.
return x.Name.CompareTo(y.Name);
}
对列表进行排序(即您希望对其进行排序而不是创建新列表),则将名称比较添加到比较器的末尾。像这样:
MyList.Sort(new ArtikelTypeAndNameComparer());
进行排序的代码是:
{{1}}