Skip to content

Commit

Permalink
add - doc - Added alphanumeric compare
Browse files Browse the repository at this point in the history
---

We've added a way to alphanumerically compare!

---

Type: add
Breaking: False
Doc Required: True
Backport Required: False
Part: 1/1
  • Loading branch information
AptiviCEO committed Jul 8, 2024
1 parent 9fa1042 commit 289d50d
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
25 changes: 25 additions & 0 deletions Textify.Tests/General/TextToolsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using Textify.General;
using Textify.General.Comparers;

namespace Textify.Tests.General
{
Expand Down Expand Up @@ -1152,6 +1153,30 @@ public void TestGetListOfRepeatedLettersWipe()
repeated.ShouldNotContainKey('o');
repeated.ShouldNotContainKey('!');
}

/// <summary>
/// Tests sorting strings alphanumerically
/// </summary>
[TestMethod]
[Description("Querying")]
public void TestSortAlphanumerically()
{
string textsAndNumbers =
"""
One
Two
Three
Test-4
Test-2
Test-29
Test-3
""";
string textsAndNumbersExpected ="One\nTest-2\nTest-3\nTest-4\nTest-29\nThree\nTwo";
string[] texts = textsAndNumbers.SplitNewLines();
string[] sorted = [.. texts.OrderBy((line) => line, new LogicalComparer())];
string made = string.Join("\n", sorted);
made.ShouldBe(textsAndNumbersExpected);
}
}

}
29 changes: 29 additions & 0 deletions Textify/General/Comparers/LogicalComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Textify Copyright (C) 2023-2024 Aptivi
//
// This file is part of Textify
//
// Textify is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Textify is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY, without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//

using System.Collections.Generic;

namespace Textify.General.Comparers
{
internal class LogicalComparer : IComparer<string>
{
public int Compare(string x, string y) =>
TextTools.CompareLogical(x, y);
}
}
73 changes: 73 additions & 0 deletions Textify/General/TextTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,5 +1031,78 @@ public static int GetLetterRepetitionPattern(this string target, int steps)
// Return the resulting dictionary
return new(letters);
}

/// <summary>
/// Logically compares the two strings ignoring the cases while treating digits (localized or not) as numbers and text as strings.
/// </summary>
/// <param name="source">Source text to compare</param>
/// <param name="compare">Comparison text</param>
/// <returns>1 if left, -1 if right, 0 if equal</returns>
public static int CompareLogical(string source, string compare)
{
string s1 = source;
if (s1 == null)
return 0;
string s2 = compare;
if (s2 == null)
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];

char[] space1 = new char[len1];
int loc1 = 0;
char[] space2 = new char[len2];
int loc2 = 0;

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]));

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;
}
}
}

0 comments on commit 289d50d

Please sign in to comment.