Browse Source

Simplify AlphanumericComparer, reduce code duplication

Vasily 5 years ago
parent
commit
8e20d2e931

+ 2 - 6
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -387,15 +387,12 @@ namespace MediaBrowser.Controller.Entities
 
             while (thisMarker < s1.Length)
             {
-                if (thisMarker >= s1.Length)
-                {
-                    break;
-                }
                 char thisCh = s1[thisMarker];
 
                 var thisChunk = new StringBuilder();
+                bool isNumeric = char.IsDigit(thisCh);
 
-                while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0])))
+                while ((thisMarker < s1.Length) && (char.IsDigit(thisCh) == isNumeric))
                 {
                     thisChunk.Append(thisCh);
                     thisMarker++;
@@ -406,7 +403,6 @@ namespace MediaBrowser.Controller.Entities
                     }
                 }
 
-                var isNumeric = thisChunk.Length > 0 && char.IsDigit(thisChunk[0]);
                 list.Add(new Tuple<StringBuilder, bool>(thisChunk, isNumeric));
             }
 

+ 15 - 17
Emby.Server.Implementations/Sorting/AlphanumComparator.cs → MediaBrowser.Controller/Sorting/AlphanumComparator.cs

@@ -2,7 +2,7 @@ using System.Collections.Generic;
 using System.Text;
 using MediaBrowser.Controller.Sorting;
 
-namespace Emby.Server.Implementations.Sorting
+namespace MediaBrowser.Controller.Sorting
 {
     public class AlphanumComparator : IComparer<string>
     {
@@ -31,8 +31,9 @@ namespace Emby.Server.Implementations.Sorting
 
                 var thisChunk = new StringBuilder();
                 var thatChunk = new StringBuilder();
+                bool thisNumeric = char.IsDigit(thisCh), thatNumeric = char.IsDigit(thatCh);
 
-                while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0])))
+                while ((thisMarker < s1.Length) && (char.IsDigit(thisCh) == thisNumeric))
                 {
                     thisChunk.Append(thisCh);
                     thisMarker++;
@@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.Sorting
                     }
                 }
 
-                while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || SortHelper.InChunk(thatCh, thatChunk[0])))
+                while ((thatMarker < s2.Length) && (char.IsDigit(thatCh) == thatNumeric))
                 {
                     thatChunk.Append(thatCh);
                     thatMarker++;
@@ -54,38 +55,35 @@ namespace Emby.Server.Implementations.Sorting
                     }
                 }
 
-                int result = 0;
+
                 // If both chunks contain numeric characters, sort them numerically
-                if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
+                if (thisNumeric && thatNumeric)
                 {
-                    if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk))
-                    {
-                        return 0;
-                    }
-                    if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk))
+                    if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk)
+                        || !int.TryParse(thatChunk.ToString(), out thatNumericChunk))
                     {
                         return 0;
                     }
 
                     if (thisNumericChunk < thatNumericChunk)
                     {
-                        result = -1;
+                        return -1;
                     }
 
                     if (thisNumericChunk > thatNumericChunk)
                     {
-                        result = 1;
+                        return 1;
                     }
                 }
                 else
                 {
-                    result = thisChunk.ToString().CompareTo(thatChunk.ToString());
+                    int result = thisChunk.ToString().CompareTo(thatChunk.ToString());
+                    if (result != 0)
+                    {
+                        return result;
+                    }
                 }
 
-                if (result != 0)
-                {
-                    return result;
-                }
             }
 
             return 0;

+ 5 - 117
MediaBrowser.Controller/Sorting/SortExtensions.cs

@@ -7,137 +7,25 @@ namespace MediaBrowser.Controller.Sorting
 {
     public static class SortExtensions
     {
+        private static IComparer<string> _comparer = new AlphanumComparator();
         public static IEnumerable<T> OrderByString<T>(this IEnumerable<T> list, Func<T, string> getName)
         {
-            return list.OrderBy(getName, new AlphanumComparator());
+            return list.OrderBy(getName, _comparer);
         }
 
         public static IEnumerable<T> OrderByStringDescending<T>(this IEnumerable<T> list, Func<T, string> getName)
         {
-            return list.OrderByDescending(getName, new AlphanumComparator());
+            return list.OrderByDescending(getName, _comparer);
         }
 
         public static IOrderedEnumerable<T> ThenByString<T>(this IOrderedEnumerable<T> list, Func<T, string> getName)
         {
-            return list.ThenBy(getName, new AlphanumComparator());
+            return list.ThenBy(getName, _comparer);
         }
 
         public static IOrderedEnumerable<T> ThenByStringDescending<T>(this IOrderedEnumerable<T> list, Func<T, string> getName)
         {
-            return list.ThenByDescending(getName, new AlphanumComparator());
-        }
-
-        private class AlphanumComparator : IComparer<string>
-        {
-            private enum ChunkType { Alphanumeric, Numeric };
-
-            private static bool InChunk(char ch, char otherCh)
-            {
-                var type = ChunkType.Alphanumeric;
-
-                if (char.IsDigit(otherCh))
-                {
-                    type = ChunkType.Numeric;
-                }
-
-                if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
-                    || (type == ChunkType.Numeric && !char.IsDigit(ch)))
-                {
-                    return false;
-                }
-
-                return true;
-            }
-
-            public static int CompareValues(string s1, string s2)
-            {
-                if (s1 == null || s2 == null)
-                {
-                    return 0;
-                }
-
-                int thisMarker = 0, thisNumericChunk = 0;
-                int thatMarker = 0, thatNumericChunk = 0;
-
-                while ((thisMarker < s1.Length) || (thatMarker < s2.Length))
-                {
-                    if (thisMarker >= s1.Length)
-                    {
-                        return -1;
-                    }
-                    else if (thatMarker >= s2.Length)
-                    {
-                        return 1;
-                    }
-                    char thisCh = s1[thisMarker];
-                    char thatCh = s2[thatMarker];
-
-                    var thisChunk = new StringBuilder();
-                    var thatChunk = new StringBuilder();
-
-                    while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || InChunk(thisCh, thisChunk[0])))
-                    {
-                        thisChunk.Append(thisCh);
-                        thisMarker++;
-
-                        if (thisMarker < s1.Length)
-                        {
-                            thisCh = s1[thisMarker];
-                        }
-                    }
-
-                    while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || InChunk(thatCh, thatChunk[0])))
-                    {
-                        thatChunk.Append(thatCh);
-                        thatMarker++;
-
-                        if (thatMarker < s2.Length)
-                        {
-                            thatCh = s2[thatMarker];
-                        }
-                    }
-
-                    int result = 0;
-                    // If both chunks contain numeric characters, sort them numerically
-                    if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0]))
-                    {
-                        if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk))
-                        {
-                            return 0;
-                        }
-                        if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk))
-                        {
-                            return 0;
-                        }
-
-                        if (thisNumericChunk < thatNumericChunk)
-                        {
-                            result = -1;
-                        }
-
-                        if (thisNumericChunk > thatNumericChunk)
-                        {
-                            result = 1;
-                        }
-                    }
-                    else
-                    {
-                        result = thisChunk.ToString().CompareTo(thatChunk.ToString());
-                    }
-
-                    if (result != 0)
-                    {
-                        return result;
-                    }
-                }
-
-                return 0;
-            }
-
-            public int Compare(string x, string y)
-            {
-                return CompareValues(x, y);
-            }
+            return list.ThenByDescending(getName, _comparer);
         }
     }
 }

+ 0 - 25
MediaBrowser.Controller/Sorting/SortHelper.cs

@@ -1,25 +0,0 @@
-namespace MediaBrowser.Controller.Sorting
-{
-    public static class SortHelper
-    {
-        private enum ChunkType { Alphanumeric, Numeric };
-
-        public static bool InChunk(char ch, char otherCh)
-        {
-            var type = ChunkType.Alphanumeric;
-
-            if (char.IsDigit(otherCh))
-            {
-                type = ChunkType.Numeric;
-            }
-
-            if ((type == ChunkType.Alphanumeric && char.IsDigit(ch))
-                || (type == ChunkType.Numeric && !char.IsDigit(ch)))
-            {
-                return false;
-            }
-
-            return true;
-        }
-    }
-}