2013-03-22 42 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 
}