2013-03-22 86 views
0

我确定这很简单,但它让我难以置信。我希望简化字母排序,但把Ds放在As和Bs之间。我想我想要一个自定义的IComparer来做到这一点。我如何使用.NET中的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); 
    } 
} 

回答

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); 
} 
+0

谢谢你们!我认为这是对的。我可以详细说明一下吗?比方说,我希望我的所有“N/A”都是在空字符串之后,但在任何其他字母字符串之前。 – GaryB96 2013-03-22 19:55:09

+0

@ GaryB96:那么你可能会遇到特殊的“N/A”,检查它是否与“”相同,并返回-1作为其他任何事情。你添加的规则越多,它就越乱 – 2013-03-22 20:23:32

0

它会更容易使用LINQ to修改排序顺序:

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

实际EvaluationFunction取决于排序您的实际业务需求。

您查看的顺序对我来说没什么意义,我无法猜测规则(为什么“D”在那里?),但如果顺序是A1,A2,B1,B2, C,d,E

你EvaluationFunction可以是:

string EvaluationFunction(string s){ 
    return string.Format("{0,-3}", s); // pads s on the left with spaces, up to 3 
}