2016-01-06 58 views
3

假設我有多個部分的問題列表和每個問題有一個像11a1b22a等一個QuestionNumber。我想使用linq-to-entities從數據庫中提取問題列表,但是按QuestionNumber排序。問題是,而不是用正確的順序,它將使用字典序像C#字母順序號碼列表

1 
11 
11a 
11b 
1a 
1b 
2 
22 

我至今是一個自定義比較:

public class QuestionCompare : IComparer<Question> 
{ 
    public int Compare(Question x, Question y) 
    { 
     string a = x.QuestionNumber; 
     string b = y.QuestionNumber; 

     if (a == b) 
     { 
      return 0; 
     } 

     int aInt; 
     bool aBool = Int32.TryParse(new String(a.Where(Char.IsDigit).ToArray()), out aInt); 
     int bInt; 
     bool bBool = Int32.TryParse(new String(b.Where(Char.IsDigit).ToArray()), out bInt); 
     if (aBool) 
     { 
      if (bBool) 
      { 
       if (aInt > bInt) 
       { 
        return 1; 
       } 
       else if (aInt < bInt) 
       { 
        return -1; 
       } 
       else 
       { 
        string aLetter = new String(a.Where(Char.IsLetter).ToArray()); 
        string bLetter = new String(a.Where(Char.IsLetter).ToArray()); 
        return StringComparer.CurrentCulture.Compare(aLetter, bLetter); 
       } 
      } 
      else 
      { 
       return 1; 
      } 
     } 
     else 
     { 
      if (bBool) 
      { 
       return -1; 
      } 
      else 
      { 
       return StringComparer.CurrentCulture.Compare(a, b); 
      } 
     } 

     return 0; 
    } 
} 

你可以叫Array.Sort(questionArray,new QuestionCompare())把問題按正確的順序。

但是,我覺得這是一個常見的定義良好的順序,所以我想知道是否有更好的實現,甚至可能是內置到.Net框架中的東西。

+0

這是自然排序,因此,如果您使用排序列表每例將進行排序這種方式,甚至使用的Array.Sort(陣列)超載 – Gusman

+0

@Gusman我覺得OP意識到。這是問題和自定義比較器的原因。 – ryanyuyu

+0

閱讀他最後的聲明:*「但是,我覺得這是一個常見的定義良好的順序,所以我想知道是否有更好的實現,甚至可能是內置到.Net框架中的東西。」* – Gusman

回答

1

這個比較器工作正常,並且短一點。

public class QuestionCompare : IComparer<Question> 
{ 
    public int Compare(Question x, Question y) 
    { 
     string a = x.QuestionNumber; 
     string b = y.QuestionNumber; 

     var aDigits = new string(a.TakeWhile(c => char.IsDigit(c)).ToArray()); 
     var bDigits = new string(b.TakeWhile(c => char.IsDigit(c)).ToArray()); 

     int aInt = String.IsNullOrEmpty(aDigits) ? 0 : int.Parse(aDigits); 
     int bInt = String.IsNullOrEmpty(bDigits) ? 0 : int.Parse(bDigits); 

     return aInt != bInt ? aInt.CompareTo(bInt) : a.CompareTo(b); 
    } 
} 
+0

不錯。一些測試表明你的代碼也稍微快一點。如果其中一個項目沒有數字,它會做一些奇怪的事情 - 這是由於某種原因在0之後但在1之前。 – Matthew

+0

我得到了一個印象,總是有一個數字後跟一個可選的字母,而且不會有'0'的問題。您可以將默認零改爲「-1」或「int.MaxValue」,看看它們是否按照您的預期行事。 – Enigmativity