2016-05-17 36 views
1

我有一個任務可以對DataTable中的一組值進行排序。 BUT棘手的部分是值的特殊字符,如'。'或' - '以及負值。以下圖片是我當前的輸出: enter image description here使用特殊字符對一組值進行排序

數據以';'分隔圖片中。 我正在使用以下代碼對數據進行排序。

DataTable myDataTable = new DataTable(); 
     myDataTable.Columns.Add("SN", typeof(string)); 
     string myValues = ""; 

     if (!File.Exists("d:\\DUDBC-values.txt")) //DUDBC-values.txt 
     { 
      Console.WriteLine("No file found"); 
      Console.ReadKey(); 
      return; 
     } 
     StreamReader file = new StreamReader("d:\\DUDBC-values.txt"); 
     string line; 
     while ((line = file.ReadLine()) != null) 
     { 
      myValues += line; 
      myValues += ";"; 
     } 
     file.Close(); 


     string[] myValuesArray = myValues.Split(';'); 
     myValuesArray = myValuesArray.Take(myValuesArray.Count() - 1).ToArray(); 

     foreach (string myValue in myValuesArray) 
     { 
      DataRow myRow = myDataTable.NewRow(); 
      myRow["SN"] = myValue; 
      myDataTable.Rows.Add(myRow); 
     } 

     string beforeSort = string.Join(";", myDataTable.AsEnumerable().Select(x => x["SN"])); 
     Console.WriteLine("Before Sorting:"); 
     Console.WriteLine(); 

     Console.WriteLine(beforeSort); 

     Console.WriteLine(); 


     IEnumerable<DataRow> sortedValues = myDataTable.AsEnumerable() 
               .OrderBy(x => 
               { 
                string currentStringValue = x["SN"].ToString(); 
                char[] SplitChar = new char[] { '.', '-' }; 
                string[] currentStringValueArray = new string[1]; 
                try 
                { 
                 float val = float.Parse(currentStringValue); 
                 currentStringValueArray[0] = currentStringValue; 

                } 
                catch { 
                currentStringValueArray = currentStringValue.Split(SplitChar); 
                } 

                string currentPart = ""; 
                int currentPartNumeric = 0; 


                if (currentStringValueArray.Length > 1) 
                { 
                 for (int i = 0; i < currentStringValueArray.Length; i++) 
                 { 
                  if (int.TryParse(currentStringValueArray[i], out currentPartNumeric)) 
                  { 
                   if (i >= 1) 
                    currentPart += "."; 
                   currentPart += currentPartNumeric.ToString(); 
                  } 
                  else 
                  { 
                   try 
                   { 
                    if (i >= 1) 
                     currentPart += "."; 
                    currentPart += (((int)(char.ToUpper(char.Parse(currentStringValueArray[i])))) - 64).ToString(); 
                   } 
                   catch { } 
                  } 

                 } 
                 return Convert.ToString(currentPart, CultureInfo.InvariantCulture); 
                } 

                else 
                 return 0m.ToString(); 
               }); 
string afterSort = string.Join(";", sortedValues.Select(x => x["SN"])); 
     Console.WriteLine("After Sorting:"); 
     Console.WriteLine(); 

     Console.WriteLine(afterSort); 
     //Copy to your existing datatable 
     myDataTable = sortedValues.CopyToDataTable(); 
     Console.ReadKey(); 

,我希望它是這樣的:

-1 
1.1.a.1 
1.2.a.1 
1.2.a.2 
1.2.a.3 
1.3.1 
2.1.2 
2.1a.1 
2.1a.2 
2.5 
2.6.1 
2.7.1 
2.7.2 
2.7.16 
2.25a 
2.25b 
2.42.1 
2.42.2 
3.1.1 
3.1.2 
3.5.2 
3.6a.1 
3.6a.2 
3.6b.2 
5.1a.1 
5.1a.2 
5.1a.3 
5.1b.1 
5.1b.2 
5.1b.6 
6.3.1 
6.3.2 
6.3.3 
6.3.4 
6.3.5 
6.5.1 
6.5.2-C11 
6.5.3-C12 
17.06.01.b.i 
17.06.02.b.i 
17.06.02.b.vi 
18.01.b 
18.02.01.b.iii 
1000 

我到底做錯了什麼?請幫助。我還問過這種類型的問題in this post,直到用戶不斷輸入不同類型的值。

+0

好的。但是問題是什麼?您尚未解釋您希望使用您的代碼生成什麼以及它實際生成的內容。 – ChrisF

+0

對不起,我現在編輯了我的問題。 – Skaranjit

回答

2

它看起來像你需要排序在所謂的「自然排序」。

有一個Windows API函數StrCmpLogicalW(),您可以使用它來做這樣的比較。

您可以在一組擴展方法包裝這個排序List<T>或數組,像這樣:

public static class NaturalSortExt 
{ 
    /// <summary>Sorts a list in "Natural sort order", i.e. "9" sorts before "10".</summary> 
    /// <typeparam name="T">The type of elements in the list to be sorted.</typeparam> 
    /// <param name="self">The list to be sorted.</param> 
    /// <param name="stringSelector">A projection to convert list elements to strings for comparision.</param> 

    public static void SortNatural<T>(this List<T> self, Func<T, string> stringSelector) 
    { 
     self.Sort((lhs, rhs) => StrCmpLogicalW(stringSelector(lhs), stringSelector(rhs))); 
    } 

    /// <summary>Sorts a list in "Natural sort order", i.e. "9" sorts before "10".</summary> 
    /// <param name="self">The list to be sorted.</param> 

    public static void SortNatural(this List<string> self) 
    { 
     self.Sort(StrCmpLogicalW); 
    } 

    /// <summary>Sorts an array in "Natural sort order", i.e. "9" sorts before "10".</summary> 
    /// <param name="self">The array to be sorted.</param> 

    public static void SortNatural(this string[] self) 
    { 
     Array.Sort(self, StrCmpLogicalW); 
    } 

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] 
    static extern int StrCmpLogicalW(string lhs, string rhs); 
} 

那麼你可以排序的如表現在下面的示例代碼陣列(或List<T>):

class Program 
{ 
    static void Main() 
    { 
     string[] test = 
     { 
      "3.1.2", 
      "1.2.a.1", 
      "1.2.a.2", 
      "1.3.1", 
      "2.1.2", 
      "2.1a.2", 
      "2.1a.1", 
      "-1", 
      "2.5", 
      "2.7.1", 
      "1.1.a.1", 
      "2.7.16", 
      "2.7.2", 
      "2.25a", 
      "2.6.1", 
      "5.1a.3", 
      "2.42.2", 
      "2.25b", 
      "2.42.1", 
      "3.6a.2", 
      "5.1b.1", 
      "3.1.1", 
      "3.5.2", 
      "3.6a.1", 
      "3.6b.2", 
      "5.1a.1", 
      "1.2.a.3", 
      "5.1b.2", 
      "5.1b.6", 
      "6.3.1", 
      "6.3.2", 
      "17.06.02.b.i", 
      "6.3.3", 
      "5.1a.2", 
      "6.3.4", 
      "6.3.5", 
      "6.5.1", 
      "1000", 
      "6.5.2-C11", 
      "6.5.3-C12", 
      "17.06.01.b.i", 
      "17.06.02.b.vi", 
      "18.01.b", 
      "18.02.01.b.iii" 
     }; 

     string[] expected = 
     { 
      "-1", 
      "1.1.a.1", 
      "1.2.a.1", 
      "1.2.a.2", 
      "1.2.a.3", 
      "1.3.1", 
      "2.1.2", 
      "2.1a.1", 
      "2.1a.2", 
      "2.5", 
      "2.6.1", 
      "2.7.1", 
      "2.7.2", 
      "2.7.16", 
      "2.25a", 
      "2.25b", 
      "2.42.1", 
      "2.42.2", 
      "3.1.1", 
      "3.1.2", 
      "3.5.2", 
      "3.6a.1", 
      "3.6a.2", 
      "3.6b.2", 
      "5.1a.1", 
      "5.1a.2", 
      "5.1a.3", 
      "5.1b.1", 
      "5.1b.2", 
      "5.1b.6", 
      "6.3.1", 
      "6.3.2", 
      "6.3.3", 
      "6.3.4", 
      "6.3.5", 
      "6.5.1", 
      "6.5.2-C11", 
      "6.5.3-C12", 
      "17.06.01.b.i", 
      "17.06.02.b.i", 
      "17.06.02.b.vi", 
      "18.01.b", 
      "18.02.01.b.iii", 
      "1000" 
     }; 

     test.SortNatural(); 

     Debug.Assert(test.SequenceEqual(expected)); 

     Console.WriteLine(string.Join("\n", test)); 
    } 
} 
+0

耶穌基督。我發明了很多次車輪。謝謝! – Eugene

+0

是的,這正是我的許多數據所需要的,但它在負值時失敗。但是我想考慮一些限制。總而言之,它的工作。謝謝:D – Skaranjit