AlphanumComparator.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using System.Collections.Generic;
  2. using System.Text;
  3. using MediaBrowser.Controller.Sorting;
  4. namespace Emby.Server.Implementations.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. while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0])))
  31. {
  32. thisChunk.Append(thisCh);
  33. thisMarker++;
  34. if (thisMarker < s1.Length)
  35. {
  36. thisCh = s1[thisMarker];
  37. }
  38. }
  39. while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || SortHelper.InChunk(thatCh, thatChunk[0])))
  40. {
  41. thatChunk.Append(thatCh);
  42. thatMarker++;
  43. if (thatMarker < s2.Length)
  44. {
  45. thatCh = s2[thatMarker];
  46. }
  47. }
  48. int result = 0;
  49. // If both chunks contain numeric characters, sort them numerically
  50. if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
  51. {
  52. if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk))
  53. {
  54. return 0;
  55. }
  56. if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk))
  57. {
  58. return 0;
  59. }
  60. if (thisNumericChunk < thatNumericChunk)
  61. {
  62. result = -1;
  63. }
  64. if (thisNumericChunk > thatNumericChunk)
  65. {
  66. result = 1;
  67. }
  68. }
  69. else
  70. {
  71. result = thisChunk.ToString().CompareTo(thatChunk.ToString());
  72. }
  73. if (result != 0)
  74. {
  75. return result;
  76. }
  77. }
  78. return 0;
  79. }
  80. public int Compare(string x, string y)
  81. {
  82. return CompareValues(x, y);
  83. }
  84. }
  85. }