0

我敢肯定这很简单,但它让我很难过。我想简化地对我的字母进行排序,但将 Ds 放在 As 和 Bs 之间。我想我想要一个自定义的 IComparer 来做到这一点。

我将如何完成这个 IComparer 实现以传递我的断言?IComparer 文档说,如果 x < y,则返回小于 0,但是小于零有关系?抓着我的头。

private static void Main(string[] args)
{
    var letters = new List<string> { "A2", "E", "B1", "A1", "D", "C", "B2" };
    var sorted = new List<string> { "A1", "A2", "D", "B1", "B2", "C", "E" };

    letters.Sort(new MyComparer());

    Assert.IsTrue(letters.SequenceEqual(sorted));
}

/// <summary>
/// Sorts D between A and B
/// </summary>
private class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        if (string.Equals(x, "D"))
        {
            // return what?
        }
        return string.CompareOrdinal(x, y);
    }
}
4

2 回答 2

2

但比零小多少有关系吗

不,一点也不。

基本上,每次比较都必须从三个选项中给出一个结果:

  • 第一个值小于第二个值
  • 值相等
  • 第一个值大于第二个值

因此,要使“D”介于“A”和“B”之间,您可以使用以下内容:

public int Compare(string x, string y)
{
    if (x == y)
    {
        return 0;
    }
    if (x == "D")
    {
        // Unless y is *actually* "B", we can just
        // pretend that x is "B". (So it will be after any "A", but before
        // any other "Bxyz".)
        if (y == "B")
        {
            return -1;
        }
        return "B".CompareTo(y);
    }
    // Ditto, basically. Alternatively you could call Compare(y, x)
    // and invert the result, but *don't* just negate it, as it does the
    // wrong thing with int.MinValue...
    if (x == "D")
    {
        if (x == "B")
        {
            return 1;
        }
        return x.CompareTo("B");
    }
    return x.CompareTo(y);
}
于 2013-03-22T18:59:17.220 回答
1

使用 Linq 修改排序顺序会更容易:

letters.OrderBy(x=>EvaluationFunction(x));

实际EvaluationFunction要根据你的实际业务需求进行排序。

你看的顺序对我来说没有多大意义,我猜不出规则(为什么“D”在那里?)但如果顺序是 A1、A2、B1、B2、C、D,乙

您的 EvaluationFunction 可以是:

string EvaluationFunction(string s){
    return  string.Format("{0,-3}", s); // pads s on the left with spaces, up to 3
}
于 2013-03-22T19:07:06.820 回答