2016-01-13 69 views
-2

我想創建一個與How to create custom common number-text comparer in C# to sort numeric/string list?中描述的類似的數字文本比較器。在C#中對數字/字符串列表進行排序的自定義常見數字文本比較器?

public class NumberTextComparer : IComparer<string> 
    { 
     public int Compare(string s1, string s2) 
     { 
      double number1, number2; 
      var isS1Numeric = double.TryParse(s1, out number1); 
      var isS2Numeric = double.TryParse(s2, out number2); 

      if (isS1Numeric && isS2Numeric) 
      { 
       if (number1 > number2) return 1; 
       if (number1 < number2) return -1; 
       return 0; 
      } 
      if (isS1Numeric) 
       return 1; 
      if (isS2Numeric) 
       return -1; 

      bool s1StartsWithLetter = char.IsLetter(s1.FirstOrDefault()); 
      bool s2StartsWithLetter = char.IsLetter(s2.FirstOrDefault()); 

      if (s1StartsWithLetter == s2StartsWithLetter) 
       return String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase); 
      if (s1StartsWithLetter) 
       return -1; 
      return 1; 
     } 
    } 

var numericList = new List<string>{"100", "--", "-0.98", "N/A", "0.00", "-888"}; 
var stringList = new List<string> {"Smith", "--", "Peter", "", "Jim", "Ken", "NA"}; 

Console.WriteLine(String.Join(", ", numericList.OrderBy(v => v, new NumberTextComparer()))); 
Console.WriteLine(String.Join(", ", stringList.OrderBy(v => v, new NumberTextComparer()))); 

其給出以下輸出:

  1. N/A, - ,-888,-0.98,0.00,100
  2. 吉姆,肯,NA,彼得·史密斯,, -

但我想要的字符串排序中:""--應該放在第一位,而不是最後的升序排列。數字排序與例外一樣。

所以預期的結果將是:

  1. 數字排序升序 - >N/A, --,-888, -0.98, 0.00, 100
  2. 字符串排序升序 - >, --, Jim, Ken, NA, Peter, Smith

是否有可能實現這一目標?

+0

你試過了什麼?請提供一個很好的[mcve],以精確說明該代碼的作用,以及與您想要的不同之處。 –

+0

已更新爲程式碼片段。謝謝! –

+0

感謝您的代碼。不幸的是,我還沒有真正理解這個問題。兩個問題:** 1)**您的「預期結果」示例看起來並不一致。首先,字符串'「 - 」'在N/A之後「,但在第二個字符之前它出現在」「NA」之前(以及所有其他非數字)。從你的描述中,我想你會在''N/A''之前也想要它。爲什麼不? –

回答

0

根據我的理解,在數字和字符串數據的情況下,您需要2種不同的排序行爲。所以你可以通過傳遞下面所要求的類型來達到這個目的 -

public enum SortColumnType 
{ 
     Numeric=1, 
     String=2 
} 

public class NumberTextComparer : IComparer<string> 
    { 
     public SortColumnType ColumnType { get; set; } 

     public NumberTextComparer(SortColumnType columnType) 
     { 
      ColumnType = columnType; 
     } 

     private int CustomNumberSort(string s1, string s2) 
     { 
      double number1, number2; 
      var isS1Numeric = double.TryParse(s1, out number1); 
      var isS2Numeric = double.TryParse(s2, out number2); 

      if (isS1Numeric && isS2Numeric) 
      { 
       if (number1 > number2) return 1; 
       if (number1 < number2) return -1; 
       return 0; 
      } 
      if (isS1Numeric) 
       return 1; 
      if (isS2Numeric) 
       return -1; 

      var s1StartsWithLetter = !string.IsNullOrEmpty(s1) && char.IsLetterOrDigit(s1[0]); 
      var s2StartsWithLetter = !string.IsNullOrEmpty(s2) && char.IsLetterOrDigit(s2[0]); 

      if (s1StartsWithLetter == s2StartsWithLetter) 
       return String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase); 
      if (s1StartsWithLetter) 
       return -1; 
      return 1; 
     } 

     public int Compare(string s1, string s2) 
     { 
      return ColumnType.Equals(SortColumnType.Numeric) 
       ? CustomNumberSort(s1, s2) 
       : String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase); 
     } 
    } 

stringList.OrderBy(str => str, new NumberTextComparer(SortColumnType.String)); 
numericList.OrderBy(str => str, new NumberTextComparer(SortColumnType.Numeric)); 
+0

謝謝Sumit!此解決方案有效。 –

相關問題