diff --git a/Pages/Index.cshtml.cs b/Pages/Index.cshtml.cs
index e52d400..cf64a4f 100644
--- a/Pages/Index.cshtml.cs
+++ b/Pages/Index.cshtml.cs
@@ -1,4 +1,4 @@
-using System;
+using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -36,7 +36,7 @@ namespace webmusic.Pages
dirs.Sort();
files = Directory.GetFiles(fullpath).Select(Path.GetFileName).ToList();
files.RemoveAll(p => p.EndsWith(".m3u"));
- files.Sort(new NumericComparer());
+ files.Sort(new AlphanumComparatorFast());
}
public string Encode(string str)
@@ -45,25 +45,96 @@ namespace webmusic.Pages
.Replace("?", "%3F").Replace("&", "%26")
.Replace(" ", "%20");
}
-
- public class NumericComparer : IComparer
+
+ public class AlphanumComparatorFast : IComparer
{
public int Compare(string x, string y)
{
- var regex = new Regex(@"^\d+");
-
- // run the regex on both strings
- var xRegexResult = regex.Match(x);
- var yRegexResult = regex.Match(y);
-
- // check if they are both numbers
- if (xRegexResult.Success && yRegexResult.Success)
+ string s1 = x;
+ if (s1 == null)
{
- return int.Parse(xRegexResult.Value).CompareTo(int.Parse(yRegexResult.Value));
+ return 0;
}
- // otherwise return as string comparison
- return string.Compare(x, y, StringComparison.Ordinal);
+ if (!(y is string s2))
+ {
+ return 0;
+ }
+
+ int len1 = s1.Length;
+ int len2 = s2.Length;
+ int marker1 = 0;
+ int marker2 = 0;
+
+ // Walk through two the strings with two markers.
+ while (marker1 < len1 && marker2 < len2)
+ {
+ char ch1 = s1[marker1];
+ char ch2 = s2[marker2];
+
+ // Some buffers we can build up characters in for each chunk.
+ char[] space1 = new char[len1];
+ int loc1 = 0;
+ char[] space2 = new char[len2];
+ int loc2 = 0;
+
+ // Walk through all following characters that are digits or
+ // characters in BOTH strings starting at the appropriate marker.
+ // Collect char arrays.
+ do
+ {
+ space1[loc1++] = ch1;
+ marker1++;
+
+ if (marker1 < len1)
+ {
+ ch1 = s1[marker1];
+ }
+ else
+ {
+ break;
+ }
+ } while (char.IsDigit(ch1) == char.IsDigit(space1[0]));
+
+ do
+ {
+ space2[loc2++] = ch2;
+ marker2++;
+
+ if (marker2 < len2)
+ {
+ ch2 = s2[marker2];
+ }
+ else
+ {
+ break;
+ }
+ } while (char.IsDigit(ch2) == char.IsDigit(space2[0]));
+
+ // If we have collected numbers, compare them numerically.
+ // Otherwise, if we have strings, compare them alphabetically.
+ string str1 = new string(space1);
+ string str2 = new string(space2);
+
+ int result;
+
+ if (char.IsDigit(space1[0]) && char.IsDigit(space2[0]))
+ {
+ int thisNumericChunk = int.Parse(str1);
+ int thatNumericChunk = int.Parse(str2);
+ result = thisNumericChunk.CompareTo(thatNumericChunk);
+ }
+ else
+ {
+ result = str1.CompareTo(str2);
+ }
+
+ if (result != 0)
+ {
+ return result;
+ }
+ }
+ return len1 - len2;
}
}
}