AlphanumComparator.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using System.Collections.Generic;
  2. using System.Text;
  3. using MediaBrowser.Controller.Sorting;
  4. namespace MediaBrowser.Controller.Sorting
  5. {
  6. public class AlphanumComparator : IComparer<string>
  7. {
  8. public static int CompareValues(string s1, string s2)
  9. {
  10. if (s1 == null || s2 == null)
  11. {
  12. return 0;
  13. }
  14. int thisMarker = 0, thisNumericChunk = 0;
  15. int thatMarker = 0, thatNumericChunk = 0;
  16. while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
  17. {
  18. if (thisMarker >= s1.Length)
  19. {
  20. return -1;
  21. }
  22. else if (thatMarker >= s2.Length)
  23. {
  24. return 1;
  25. }
  26. char thisCh = s1[thisMarker];
  27. char thatCh = s2[thatMarker];
  28. var thisChunk = new StringBuilder();
  29. var thatChunk = new StringBuilder();
  30. bool thisNumeric = char.IsDigit(thisCh), thatNumeric = char.IsDigit(thatCh);
  31. while (thisMarker < s1.Length && char.IsDigit(thisCh) == thisNumeric)
  32. {
  33. thisChunk.Append(thisCh);
  34. thisMarker++;
  35. if (thisMarker < s1.Length)
  36. {
  37. thisCh = s1[thisMarker];
  38. }
  39. }
  40. while (thatMarker < s2.Length && char.IsDigit(thatCh) == thatNumeric)
  41. {
  42. thatChunk.Append(thatCh);
  43. thatMarker++;
  44. if (thatMarker < s2.Length)
  45. {
  46. thatCh = s2[thatMarker];
  47. }
  48. }
  49. // If both chunks contain numeric characters, sort them numerically
  50. if (thisNumeric && thatNumeric)
  51. {
  52. if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk)
  53. || !int.TryParse(thatChunk.ToString(), out thatNumericChunk))
  54. {
  55. return 0;
  56. }
  57. if (thisNumericChunk < thatNumericChunk)
  58. {
  59. return -1;
  60. }
  61. if (thisNumericChunk > thatNumericChunk)
  62. {
  63. return 1;
  64. }
  65. }
  66. else
  67. {
  68. int result = thisChunk.ToString().CompareTo(thatChunk.ToString());
  69. if (result != 0)
  70. {
  71. return result;
  72. }
  73. }
  74. }
  75. return 0;
  76. }
  77. public int Compare(string x, string y)
  78. {
  79. return CompareValues(x, y);
  80. }
  81. }
  82. }