[DatFile, DatItem] Add natural sorting, all code by motoschifo

This commit is contained in:
Matt Nadareski
2016-09-26 12:11:33 -07:00
parent 251f6aae7b
commit a3e32631fc
5 changed files with 191 additions and 8 deletions

View File

@@ -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<string>, IDisposable
{
private Dictionary<string, string[]> table;
public NaturalComparer()
{
table = new Dictionary<string, string[]>();
}
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);
}
}
}

View File

@@ -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<string>, IDisposable
{
private Dictionary<string, string[]> table;
public NaturalReversedComparer()
{
table = new Dictionary<string, string[]>();
}
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);
}
}
}

View File

@@ -3030,7 +3030,7 @@ namespace SabreTools.Helper
// Get a properly sorted set of keys // Get a properly sorted set of keys
List<string> keys = Files.Keys.ToList(); List<string> keys = Files.Keys.ToList();
keys.Sort(Style.CompareNumeric); keys.Sort(new NaturalComparer());
foreach (string key in keys) foreach (string key in keys)
{ {

View File

@@ -747,6 +747,7 @@ namespace SabreTools.Helper
{ {
roms.Sort(delegate (DatItem x, DatItem y) roms.Sort(delegate (DatItem x, DatItem y)
{ {
NaturalComparer nc = new NaturalComparer();
if (x.SystemID == y.SystemID) if (x.SystemID == y.SystemID)
{ {
if (x.SourceID == y.SourceID) if (x.SourceID == y.SourceID)
@@ -757,9 +758,9 @@ namespace SabreTools.Helper
{ {
if (Path.GetDirectoryName(x.Name) == Path.GetDirectoryName(y.Name)) 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)) 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)) 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; return true;
} }

View File

@@ -86,6 +86,8 @@
<ItemGroup> <ItemGroup>
<Compile Include="Data\Constants.cs" /> <Compile Include="Data\Constants.cs" />
<Compile Include="Data\Flags.cs" /> <Compile Include="Data\Flags.cs" />
<Compile Include="External\NaturalSort\NaturalComparer.cs" />
<Compile Include="External\NaturalSort\NaturalReversedComparer.cs" />
<Compile Include="External\OptimizedCRC.cs" /> <Compile Include="External\OptimizedCRC.cs" />
<Compile Include="External\Zlib\CRC32.cs" /> <Compile Include="External\Zlib\CRC32.cs" />
<Compile Include="External\Zlib\Deflate.cs" /> <Compile Include="External\Zlib\Deflate.cs" />