按属性排序之前按属性排序对象

时间:2016-08-17 14:33:23

标签: sorting

我尝试按类型对列表中的对象进行排序,然后使用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();
    }

1 个答案:

答案 0 :(得分:0)

有几种方法可以做到这一点。使用LINQ,您希望使用OrderByThenBy。在您的情况下,您希望先按类型排序,然后按名称排序。

按类型排序需要自定义比较。我们称之为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}}