Skip to content

Commit 99da6f2

Browse files
committed
move acronym check to method and update scoring to percentage based
1 parent bb6a911 commit 99da6f2

File tree

2 files changed

+61
-70
lines changed

2 files changed

+61
-70
lines changed

Flow.Launcher.Infrastructure/StringMatcher.cs

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,8 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
6666
var currentAcronymQueryIndex = 0;
6767
var acronymMatchData = new List<int>();
6868

69-
// preset acronymScore
70-
int acronymScore = 100;
71-
int acronymsRemainingNotMatched = 0;
72-
int acronymsMatched = 0;
69+
decimal acronymsTotalCount = 0;
70+
decimal acronymsMatched = 0;
7371

7472
var fullStringToCompareWithoutCase = opt.IgnoreCase ? stringToCompare.ToLower() : stringToCompare;
7573
var queryWithoutCase = opt.IgnoreCase ? query.ToLower() : query;
@@ -89,21 +87,18 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
8987
var indexList = new List<int>();
9088
List<int> spaceIndices = new List<int>();
9189

92-
bool spaceMet = false;
93-
9490
for (var compareStringIndex = 0; compareStringIndex < fullStringToCompareWithoutCase.Length; compareStringIndex++)
9591
{
96-
if (currentAcronymQueryIndex >= queryWithoutCase.Length && acronymsMatched > 0)
92+
// If acronyms matching successfully finished, this gets the remaining not matched acronyms for score calculation
93+
if (currentAcronymQueryIndex >= query.Length && acronymsMatched == query.Length)
9794
{
98-
if (char.IsUpper(stringToCompare[compareStringIndex]) ||
99-
char.IsNumber(stringToCompare[compareStringIndex]) ||
100-
char.IsWhiteSpace(stringToCompare[compareStringIndex]))
101-
acronymsRemainingNotMatched++;
95+
if (IsAcronym(stringToCompare, compareStringIndex))
96+
acronymsTotalCount++;
10297
continue;
10398
}
10499

105-
if (currentAcronymQueryIndex >= queryWithoutCase.Length
106-
|| allQuerySubstringsMatched && acronymScore < (int) UserSettingSearchPrecision)
100+
if (currentAcronymQueryIndex >= query.Length ||
101+
currentAcronymQueryIndex >= query.Length && allQuerySubstringsMatched)
107102
break;
108103

109104
// To maintain a list of indices which correspond to spaces in the string to compare
@@ -112,43 +107,18 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
112107
spaceIndices.Add(compareStringIndex);
113108

114109
// Acronym check
115-
if (char.IsUpper(stringToCompare[compareStringIndex]) ||
116-
char.IsNumber(stringToCompare[compareStringIndex]) ||
117-
char.IsWhiteSpace(stringToCompare[compareStringIndex]) ||
118-
spaceMet)
110+
if (IsAcronym(stringToCompare, compareStringIndex))
119111
{
120112
if (fullStringToCompareWithoutCase[compareStringIndex] ==
121113
queryWithoutCase[currentAcronymQueryIndex])
122114
{
123-
if (!spaceMet)
124-
{
125-
char currentCompareChar = stringToCompare[compareStringIndex];
126-
spaceMet = char.IsWhiteSpace(currentCompareChar);
127-
// if is space, no need to check whether upper or digit, though insignificant
128-
if (!spaceMet && compareStringIndex == 0 || char.IsUpper(currentCompareChar) ||
129-
char.IsDigit(currentCompareChar))
130-
{
131-
acronymMatchData.Add(compareStringIndex);
132-
acronymsMatched++;
133-
}
134-
}
135-
else if (!(spaceMet = char.IsWhiteSpace(stringToCompare[compareStringIndex])))
136-
{
137-
acronymMatchData.Add(compareStringIndex);
138-
acronymsMatched++;
139-
}
115+
acronymMatchData.Add(compareStringIndex);
116+
acronymsMatched++;
140117

141118
currentAcronymQueryIndex++;
142119
}
143-
else
144-
{
145-
spaceMet = char.IsWhiteSpace(stringToCompare[compareStringIndex]);
146-
// Acronym Penalty
147-
if (!spaceMet)
148-
{
149-
acronymScore -= 10;
150-
}
151-
}
120+
121+
acronymsTotalCount++;
152122
}
153123
// Acronym end
154124

@@ -217,11 +187,16 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
217187
}
218188
}
219189

220-
// return acronym Match if possible
221-
if (acronymMatchData.Count == query.Length && acronymScore >= (int) UserSettingSearchPrecision)
190+
// return acronym match if all query char matched
191+
if (acronymsMatched > 0 && acronymsMatched == query.Length)
222192
{
223-
acronymMatchData = acronymMatchData.Select(x => translationMapping?.MapToOriginalIndex(x) ?? x).Distinct().ToList();
224-
return new MatchResult(true, UserSettingSearchPrecision, acronymMatchData, acronymScore);
193+
int acronymScore = (int)(acronymsMatched / acronymsTotalCount * 100);
194+
195+
if (acronymScore >= (int)UserSettingSearchPrecision)
196+
{
197+
acronymMatchData = acronymMatchData.Select(x => translationMapping?.MapToOriginalIndex(x) ?? x).Distinct().ToList();
198+
return new MatchResult(true, UserSettingSearchPrecision, acronymMatchData, acronymScore);
199+
}
225200
}
226201

227202
// proceed to calculate score if every char or substring without whitespaces matched
@@ -238,6 +213,22 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
238213
return new MatchResult(false, UserSettingSearchPrecision);
239214
}
240215

216+
private bool IsAcronym(string stringToCompare, int compareStringIndex)
217+
{
218+
if (char.IsUpper(stringToCompare[compareStringIndex]) ||
219+
char.IsNumber(stringToCompare[compareStringIndex]) ||
220+
char.IsDigit(stringToCompare[compareStringIndex]))
221+
return true;
222+
223+
if (compareStringIndex == 0)
224+
return true;
225+
226+
if (compareStringIndex != 0 && char.IsWhiteSpace(stringToCompare[compareStringIndex - 1]))
227+
return true;
228+
229+
return false;
230+
}
231+
241232
// To get the index of the closest space which preceeds the first matching index
242233
private int CalculateClosestSpaceIndex(List<int> spaceIndices, int firstMatchIndex)
243234
{

Flow.Launcher.Test/FuzzyMatcherTest.cs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,17 @@ public void WhenGivenQueryString_ThenShouldReturn_TheDesiredScoring(
151151
[TestCase("goo", "Google Chrome", SearchPrecisionScore.Regular, true)]
152152
[TestCase("chr", "Google Chrome", SearchPrecisionScore.Low, true)]
153153
[TestCase("chr", "Chrome", SearchPrecisionScore.Regular, true)]
154+
[TestCase("chr", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Regular, false)]
154155
[TestCase("chr", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Low, true)]
155156
[TestCase("chr", "Candy Crush Saga from King", SearchPrecisionScore.Regular, false)]
156157
[TestCase("chr", "Candy Crush Saga from King", SearchPrecisionScore.None, true)]
157-
[TestCase("ccs", "Candy Crush Saga from King", SearchPrecisionScore.Regular, true)]
158+
[TestCase("ccs", "Candy Crush Saga from King", SearchPrecisionScore.Low, true)]
158159
[TestCase("cand", "Candy Crush Saga from King", SearchPrecisionScore.Regular, true)]
159-
[TestCase("cand", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Regular,
160-
false)]
160+
[TestCase("cand", "Help cure hope raise on mind entity Chrome", SearchPrecisionScore.Regular, false)]
161+
[TestCase("vsc", VisualStudioCode, SearchPrecisionScore.Regular, true)]
162+
[TestCase("vs", VisualStudioCode, SearchPrecisionScore.Regular, true)]
163+
[TestCase("vc", VisualStudioCode, SearchPrecisionScore.Regular, true)]
164+
[TestCase("vts", VisualStudioCode, SearchPrecisionScore.Regular, false)]
161165
public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual(
162166
string queryString,
163167
string compareString,
@@ -188,10 +192,8 @@ public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual(
188192

189193
[TestCase("exce", "OverLeaf-Latex: An online LaTeX editor", SearchPrecisionScore.Regular, false)]
190194
[TestCase("term", "Windows Terminal (Preview)", SearchPrecisionScore.Regular, true)]
191-
[TestCase("sql s managa", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular,
192-
false)]
193-
[TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular,
194-
false)]
195+
[TestCase("sql s managa", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)]
196+
[TestCase("sql' s manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, false)]
195197
[TestCase("sql s manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)]
196198
[TestCase("sql manag", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)]
197199
[TestCase("sql", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)]
@@ -204,18 +206,13 @@ public void WhenGivenDesiredPrecision_ThenShouldReturn_AllResultsGreaterOrEqual(
204206
[TestCase("mssms", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)]
205207
[TestCase("msms", MicrosoftSqlServerManagementStudio, SearchPrecisionScore.Regular, true)]
206208
[TestCase("chr", "Shutdown", SearchPrecisionScore.Regular, false)]
207-
[TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).",
208-
SearchPrecisionScore.Regular, false)]
209-
[TestCase("ch r", "Change settings for text-to-speech and for speech recognition (if installed).",
210-
SearchPrecisionScore.Regular, true)]
209+
[TestCase("chr", "Change settings for text-to-speech and for speech recognition (if installed).", SearchPrecisionScore.Regular, false)]
210+
[TestCase("ch r", "Change settings for text-to-speech and for speech recognition (if installed).", SearchPrecisionScore.Regular, true)]
211211
[TestCase("a test", "This is a test", SearchPrecisionScore.Regular, true)]
212212
[TestCase("test", "This is a test", SearchPrecisionScore.Regular, true)]
213213
[TestCase("cod", VisualStudioCode, SearchPrecisionScore.Regular, true)]
214214
[TestCase("code", VisualStudioCode, SearchPrecisionScore.Regular, true)]
215215
[TestCase("codes", "Visual Studio Codes", SearchPrecisionScore.Regular, true)]
216-
[TestCase("vsc", VisualStudioCode, SearchPrecisionScore.Regular, true)]
217-
[TestCase("vs", VisualStudioCode, SearchPrecisionScore.Regular, true)]
218-
[TestCase("vc", VisualStudioCode, SearchPrecisionScore.Regular, true)]
219216
public void WhenGivenQuery_ShouldReturnResults_ContainingAllQuerySubstrings(
220217
string queryString,
221218
string compareString,
@@ -300,15 +297,18 @@ public void WhenMultipleResults_ExactMatchingResult_ShouldHaveGreatestScore(
300297
$"Should be greater than{Environment.NewLine}" +
301298
$"Name of second: \"{secondName}\", Final Score: {secondScore}{Environment.NewLine}");
302299
}
303-
304-
[TestCase("vsc","Visual Studio Code", 100)]
305-
[TestCase("jbr","JetBrain Rider",100)]
306-
[TestCase("jr","JetBrain Rider",90)]
307-
[TestCase("vs","Visual Studio",100)]
308-
[TestCase("vs","Visual Studio Preview",100)]
309-
[TestCase("vsp","Visual Studio Preview",100)]
310-
[TestCase("vsp","Visual Studio",0)]
311-
[TestCase("pc","Postman Canary",100)]
300+
301+
[TestCase("vsc", "Visual Studio Code", 100)]
302+
[TestCase("jbr", "JetBrain Rider", 100)]
303+
[TestCase("jr", "JetBrain Rider", 66)]
304+
[TestCase("vs", "Visual Studio", 100)]
305+
[TestCase("vs", "Visual Studio Preview", 66)]
306+
[TestCase("vsp", "Visual Studio Preview", 100)]
307+
[TestCase("pc", "postman canary", 100)]
308+
[TestCase("psc", "Postman super canary", 100)]
309+
[TestCase("psc", "Postman super Canary", 100)]
310+
[TestCase("vsp", "Visual Studio", 0)]
311+
[TestCase("vps", "Visual Studio", 0)]
312312
public void WhenGivenAnAcronymQuery_ShouldReturnAcronymScore(string queryString, string compareString,
313313
int desiredScore)
314314
{

0 commit comments

Comments
 (0)