2017-09-05 82 views
3

我想串數列進行排序,例如串數列N1,N10,N100,N2和我期待的結果N1,N2,N10,N100但排序不起作用,我得到相同的值N1,N10,N100,N2以相同的順序。如何正確排序的一個DataTable

我寫了下面的代碼。

static class ExtensionMethod 
{ 
    public static DataTable SortAlphaNumeric(this DataTable datatable, string columnName) 
    { 
     return datatable.AsEnumerable() 
        .OrderBy(r => r.Field<String>(columnName), new CustomComparer()) 
        .CopyToDataTable(); 
    } 
} 

public class CustomComparer : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
     var numberX = Regex.Match(x, @"\d+").Value; 
     var numberY = Regex.Match(y, @"\d+").Value; 

     var alphaX = Regex.Match(x, @"[^a-z]").Value; 
     var alphaY = Regex.Match(y, @"[^a-z]").Value; 

     if (alphaX.CompareTo(alphaY) == 0) 
      return numberX.CompareTo(numberY); 
     else if (alphaX.CompareTo(alphaY) < 0) 
      return -1; 
     return 1;    
    } 
} 

// Code example 
class TestExample 
{ 
    public void Test() 
    { 
     var dt = new DataTable(); 
     dt.Columns.Add("AlphaNumeric", Type.GetType("System.String")); 
     var row = dt.NewRow(); 
     row["AlphaNumeric"] = "N1"; 
     dt.Rows.Add(row); 
     row = dt.NewRow(); 
     row["AlphaNumeric"] = "N10"; 
     dt.Rows.Add(row); 
     row = dt.NewRow(); 
     row["AlphaNumeric"] = "N100"; 
     dt.Rows.Add(row); 
     row = dt.NewRow(); 
     row["AlphaNumeric"] = "N2"; 
     dt.Rows.Add(row); 

     var orderedDt = dt.SortAlphaNumeric("AlphaNumeric"); 
    } 
} 
+0

'alpha'是_not_ A-Z? – Haukinger

+0

我的意思是alpha是所有字母A-Z和a-z。它是否有錯碼? – ehh

+0

@AntonínLejsek,好,我修好了。我剛剛將錯誤的代碼複製到問題中。由於 – ehh

回答

3

改變你的Comparer:

var numberX = int.Parse(Regex.Match(x, @"\d+").Value); 
var numberY = int.Parse(Regex.Match(y, @"\d+").Value); 
+0

哦,我錯過了,謝謝你 – ehh

+0

如果這是足夠好,但如果你有其他的字符串像'C99'甚至'X10a'你需要一個更復雜的比較器,它分析部分int,但也比較其他部分。 –

+0

是的,沒錯。在這個例子中,第一個字母已經被比較了。 – PinBack

1

我最好使用​​作爲正則表達式和比較alpha(字符串比較),然後,如果相等,int.Parsenumber和比較(整數comparsion)。如果你比較實際的數字

這讓只有兩個正則表達式的執行,而不是四個(可能編譯正則表達式,並把它在一個靜態字段將使其更快,太),和2將小於10。如果你不解析數字,你可以跳過整個正則表達式,只做一個字符串比較。

+0

好一點,我會優化它,謝謝 – ehh

0

如果數字sheme是determinsitic(始終是一個字符串+一個整數),你可以簡單地將它們存儲在兩個不同的領域(最好背在DB組成鍵是一件事畢竟)。然後它是「按字符串排序,第二個」。

如果不是,東西是要強硬。你想要的是Windows對文件進行的非常不尋常的排序。除了定製的正則表達式解決方案(但如果它是有決定意義的,你可以使用2個或更多的字段),那麼將會有StrCmpLogicalW。但是,這兩者都是非託管的,它是Windows之間的行爲變化(它是對其運行的Windows的「規範」排序,但是在Windows版本之間進行了排序)。

+0

btb,這將不得不支持舊的ASCII範圍之外的Unicode字符?我問,因爲排序這些字符串有正常化的特殊問題(https://msdn.microsoft.com/en-us/library/ebza6ck1.aspx) – Christopher