diff --git a/Sorting.Test/NaturalStringComparerTests.cs b/Sorting.Test/NaturalStringComparerTests.cs index 18402b3..9ff08fa 100644 --- a/Sorting.Test/NaturalStringComparerTests.cs +++ b/Sorting.Test/NaturalStringComparerTests.cs @@ -117,6 +117,9 @@ public void Compare_LargeNumbers_HandledCorrectly() { // Should handle numbers within integer range Assert.IsLessThan(0, _comparer.Compare("file1000000", "file9999999")); + + // Should handle numbers beyond Int32 range + Assert.IsLessThan(0, _comparer.Compare("file9999999999", "file10000000000")); } [TestMethod] diff --git a/Sorting/NaturalStringComparer.cs b/Sorting/NaturalStringComparer.cs index d79a34b..361844d 100644 --- a/Sorting/NaturalStringComparer.cs +++ b/Sorting/NaturalStringComparer.cs @@ -58,9 +58,9 @@ public int Compare(string? x, string? y) Match yMatch = yMatches[j++]; // If both chunks are numeric, compare them as numbers - if (int.TryParse(xMatch.Value, out int xNum) && int.TryParse(yMatch.Value, out int yNum)) + if (char.IsDigit(xMatch.Value[0]) && char.IsDigit(yMatch.Value[0])) { - int numComparison = xNum.CompareTo(yNum); + int numComparison = CompareNumericChunks(xMatch.Value, yMatch.Value); if (numComparison != 0) { return numComparison; @@ -79,4 +79,28 @@ public int Compare(string? x, string? y) // If we've exhausted one sequence but not the other, the shorter one comes first return xMatches.Length.CompareTo(yMatches.Length); } + + private static int CompareNumericChunks(string xChunk, string yChunk) + { + string xTrimmed = xChunk.TrimStart('0'); + string yTrimmed = yChunk.TrimStart('0'); + + if (xTrimmed.Length == 0) + { + xTrimmed = "0"; + } + + if (yTrimmed.Length == 0) + { + yTrimmed = "0"; + } + + int lengthComparison = xTrimmed.Length.CompareTo(yTrimmed.Length); + if (lengthComparison != 0) + { + return lengthComparison; + } + + return string.Compare(xTrimmed, yTrimmed, StringComparison.Ordinal); + } }