diff --git a/SabreTools.Helper/External/NaturalSort/NaturalComparer.cs b/SabreTools.Helper/External/NaturalSort/NaturalComparer.cs new file mode 100644 index 00000000..f6aa1f49 --- /dev/null +++ b/SabreTools.Helper/External/NaturalSort/NaturalComparer.cs @@ -0,0 +1,90 @@ +/* + * + * Links for info and original source code: + * + * https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/ + * http://www.codeproject.com/Articles/22517/Natural-Sort-Comparer + * + * Exact code implementation used with permission, originally by motoschifo + * + */ + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SabreTools.Helper +{ + public class NaturalComparer : Comparer, IDisposable + { + private Dictionary table; + + public NaturalComparer() + { + table = new Dictionary(); + } + + public void Dispose() + { + table.Clear(); + table = null; + } + + public override int Compare(string x, string y) + { + if (x == y) + { + return 0; + } + string[] x1, y1; + if (!table.TryGetValue(x, out x1)) + { + //x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)"); + x1 = Regex.Split(x, "([0-9]+)"); + table.Add(x, x1); + } + if (!table.TryGetValue(y, out y1)) + { + //y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)"); + y1 = Regex.Split(y, "([0-9]+)"); + table.Add(y, y1); + } + + for (int i = 0; i < x1.Length && i < y1.Length; i++) + { + if (x1[i] != y1[i]) + { + return PartCompare(x1[i], y1[i]); + } + } + if (y1.Length > x1.Length) + { + return 1; + } + else if (x1.Length > y1.Length) + { + return -1; + } + else + { + return 0; + } + } + + private static int PartCompare(string left, string right) + { + int x, y; + if (!int.TryParse(left, out x)) + { + return left.CompareTo(right); + } + + if (!int.TryParse(right, out y)) + { + return left.CompareTo(right); + } + + return x.CompareTo(y); + } + } +} diff --git a/SabreTools.Helper/External/NaturalSort/NaturalReversedComparer.cs b/SabreTools.Helper/External/NaturalSort/NaturalReversedComparer.cs new file mode 100644 index 00000000..59d3efbd --- /dev/null +++ b/SabreTools.Helper/External/NaturalSort/NaturalReversedComparer.cs @@ -0,0 +1,90 @@ +/* + * + * Links for info and original source code: + * + * https://blog.codinghorror.com/sorting-for-humans-natural-sort-order/ + * http://www.codeproject.com/Articles/22517/Natural-Sort-Comparer + * + * Exact code implementation used with permission, originally by motoschifo + * + */ + +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SabreTools.Helper +{ + public class NaturalReversedComparer : Comparer, IDisposable + { + private Dictionary table; + + public NaturalReversedComparer() + { + table = new Dictionary(); + } + + public void Dispose() + { + table.Clear(); + table = null; + } + + public override int Compare(string x, string y) + { + if (x == y) + { + return 0; + } + string[] x1, y1; + if (!table.TryGetValue(x, out x1)) + { + //x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)"); + x1 = Regex.Split(x, "([0-9]+)"); + table.Add(x, x1); + } + if (!table.TryGetValue(y, out y1)) + { + //y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)"); + y1 = Regex.Split(y, "([0-9]+)"); + table.Add(y, y1); + } + + for (int i = 0; i < x1.Length && i < y1.Length; i++) + { + if (x1[i] != y1[i]) + { + return PartCompare(x1[i], y1[i]); + } + } + if (y1.Length > x1.Length) + { + return 1; + } + else if (x1.Length > y1.Length) + { + return -1; + } + else + { + return 0; + } + } + + private static int PartCompare(string left, string right) + { + int x, y; + if (!int.TryParse(left, out x)) + { + return right.CompareTo(left); + } + + if (!int.TryParse(right, out y)) + { + return right.CompareTo(left); + } + + return -x.CompareTo(y); + } + } +} diff --git a/SabreTools.Helper/Objects/Dat/DatFile.cs b/SabreTools.Helper/Objects/Dat/DatFile.cs index d3d92495..cda6036c 100644 --- a/SabreTools.Helper/Objects/Dat/DatFile.cs +++ b/SabreTools.Helper/Objects/Dat/DatFile.cs @@ -3030,7 +3030,7 @@ namespace SabreTools.Helper // Get a properly sorted set of keys List keys = Files.Keys.ToList(); - keys.Sort(Style.CompareNumeric); + keys.Sort(new NaturalComparer()); foreach (string key in keys) { diff --git a/SabreTools.Helper/Objects/Dat/DatItem.cs b/SabreTools.Helper/Objects/Dat/DatItem.cs index 6b55b6d1..691611d0 100644 --- a/SabreTools.Helper/Objects/Dat/DatItem.cs +++ b/SabreTools.Helper/Objects/Dat/DatItem.cs @@ -747,6 +747,7 @@ namespace SabreTools.Helper { roms.Sort(delegate (DatItem x, DatItem y) { + NaturalComparer nc = new NaturalComparer(); if (x.SystemID == y.SystemID) { if (x.SourceID == y.SourceID) @@ -757,9 +758,9 @@ namespace SabreTools.Helper { if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name)) { - return Style.CompareNumeric(Path.GetFileName(x.Name), Path.GetFileName(y.Name)); + return nc.Compare(Path.GetFileName(x.Name), Path.GetFileName(y.Name)); } - return Style.CompareNumeric(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name)); + return nc.Compare(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name)); } else if ((x.Type == ItemType.Rom || x.Type == ItemType.Disk) && (y.Type != ItemType.Rom && y.Type != ItemType.Disk)) { @@ -773,16 +774,16 @@ namespace SabreTools.Helper { if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name)) { - return Style.CompareNumeric(Path.GetFileName(x.Name), Path.GetFileName(y.Name)); + return nc.Compare(Path.GetFileName(x.Name), Path.GetFileName(y.Name)); } - return Style.CompareNumeric(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name)); + return nc.Compare(Path.GetDirectoryName(x.Name), Path.GetDirectoryName(y.Name)); } } - return Style.CompareNumeric(x.MachineName, y.MachineName); + return nc.Compare(x.MachineName, y.MachineName); } - return (norename ? Style.CompareNumeric(x.MachineName, y.MachineName) : x.SourceID - y.SourceID); + return (norename ? nc.Compare(x.MachineName, y.MachineName) : x.SourceID - y.SourceID); } - return (norename ? Style.CompareNumeric(x.MachineName, y.MachineName) : x.SystemID - y.SystemID); + return (norename ? nc.Compare(x.MachineName, y.MachineName) : x.SystemID - y.SystemID); }); return true; } diff --git a/SabreTools.Helper/SabreTools.Helper.csproj b/SabreTools.Helper/SabreTools.Helper.csproj index dd46d99e..ffe965f3 100644 --- a/SabreTools.Helper/SabreTools.Helper.csproj +++ b/SabreTools.Helper/SabreTools.Helper.csproj @@ -86,6 +86,8 @@ + +