diff --git a/TextFilter.Test/TextFilterTests.cs b/TextFilter.Test/TextFilterTests.cs index 66011f5..ed384b1 100644 --- a/TextFilter.Test/TextFilterTests.cs +++ b/TextFilter.Test/TextFilterTests.cs @@ -327,6 +327,25 @@ public void RankFuzzyReturnsCorrectRanking() CollectionAssert.AreEqual(new List { "hello", "hello world", "world" }, result); } + [TestMethod] + [DataRow("hello", "hell", "say hello to everyone in the room")] + [DataRow("abc", "ab", "axxxxxxbxxxxxxc")] + [DataRow("readme", "read", "docs/ReleaseNotes/readme.md")] + [DataRow("config", "conf", "src/app/settings/config.json")] + public void RankPutsARealMatchAboveAHigherScoringNearMiss(string filter, string nearMiss, string match) + { + List result = [.. TextFilter.Rank([nearMiss, match], filter)]; + CollectionAssert.AreEqual(new List { match, nearMiss }, result); + } + + [TestMethod] + public void RankWithKeySelectorPutsARealMatchAboveAHigherScoringNearMiss() + { + List<(int Id, string Text)> items = [(1, "hell"), (2, "say hello to everyone in the room")]; + List<(int Id, string Text)> result = [.. TextFilter.Rank(items, item => item.Text, "hello")]; + CollectionAssert.AreEqual(new List<(int, string)> { (2, "say hello to everyone in the room"), (1, "hell") }, result); + } + [TestMethod] public void RankEmptyStringsReturnsEmpty() { diff --git a/TextFilter/TextFilter.cs b/TextFilter/TextFilter.cs index 65c8a36..36d6c02 100644 --- a/TextFilter/TextFilter.cs +++ b/TextFilter/TextFilter.cs @@ -201,7 +201,7 @@ public static IEnumerable Rank(IEnumerable strings, string fuzzy /// A function to extract the string key from an item. /// The fuzzy filter pattern. /// The collection of items sorted by their match score. - /// Uses fuzzy matching to rank the items by their match score. + /// Uses fuzzy matching to rank the items by their match score. Items that match the pattern always sort above items that don't, because a short near-miss can outscore a real match inside a longer string. public static IEnumerable Rank(IEnumerable items, Func keySelector, string fuzzyFilter) { Ensure.NotNull(items); @@ -213,7 +213,8 @@ public static IEnumerable Rank(IEnumerable items, Func t.score) + .OrderByDescending(t => t.isMatch) + .ThenByDescending(t => t.score) .Select(t => t.item); }