@@ -44,22 +44,12 @@ public MatchResult FuzzyMatch(string query, string stringToCompare)
44
44
/// </summary>
45
45
public MatchResult FuzzyMatch ( string query , string stringToCompare , MatchOption opt )
46
46
{
47
- if ( string . IsNullOrEmpty ( stringToCompare ) || string . IsNullOrEmpty ( query ) ) return new MatchResult ( false , UserSettingSearchPrecision ) ;
47
+ if ( string . IsNullOrEmpty ( stringToCompare ) || string . IsNullOrEmpty ( query ) )
48
+ return new MatchResult ( false , UserSettingSearchPrecision ) ;
48
49
49
50
query = query . Trim ( ) ;
50
-
51
- stringToCompare = _alphabet ? . Translate ( stringToCompare ) ?? stringToCompare ;
52
-
53
- // This also can be done by spliting the query
54
-
55
- //(var spaceSplit, var upperSplit) = stringToCompare switch
56
- //{
57
- // string s when s.Contains(' ') => (s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(w => w.First()),
58
- // default(IEnumerable<char>)),
59
- // string s when s.Any(c => char.IsUpper(c)) && s.Any(c => char.IsLower(c)) =>
60
- // (null, Regex.Split(s, @"(?<!^)(?=[A-Z])").Select(w => w.First())),
61
- // _ => ((IEnumerable<char>)null, (IEnumerable<char>)null)
62
- //};
51
+ TranslationMapping map ;
52
+ ( stringToCompare , map ) = _alphabet ? . Translate ( stringToCompare ) ?? ( stringToCompare , null ) ;
63
53
64
54
var currentQueryIndex = 0 ;
65
55
var acronymMatchData = new List < int > ( ) ;
@@ -72,28 +62,24 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
72
62
if ( currentQueryIndex >= queryWithoutCase . Length )
73
63
break ;
74
64
75
- if ( compareIndex == 0 && queryWithoutCase [ currentQueryIndex ] == char . ToLower ( stringToCompare [ compareIndex ] ) )
76
- {
77
- acronymMatchData . Add ( compareIndex ) ;
78
- currentQueryIndex ++ ;
79
- continue ;
80
- }
81
65
82
66
switch ( stringToCompare [ compareIndex ] )
83
67
{
84
- case char c when compareIndex == 0 && queryWithoutCase [ currentQueryIndex ] == char . ToLower ( stringToCompare [ compareIndex ] )
85
- || ( char . IsUpper ( c ) && char . ToLower ( c ) == queryWithoutCase [ currentQueryIndex ] )
86
- || ( char . IsWhiteSpace ( c ) && char . ToLower ( stringToCompare [ ++ compareIndex ] ) == queryWithoutCase [ currentQueryIndex ] )
87
- || ( char . IsNumber ( c ) && c == queryWithoutCase [ currentQueryIndex ] ) :
88
- acronymMatchData . Add ( compareIndex ) ;
68
+ case var c when ( compareIndex == 0 && queryWithoutCase [ currentQueryIndex ] ==
69
+ char . ToLower ( stringToCompare [ compareIndex ] ) )
70
+ || ( char . IsUpper ( c ) && char . ToLower ( c ) == queryWithoutCase [ currentQueryIndex ] )
71
+ || ( char . IsWhiteSpace ( c ) && char . ToLower ( stringToCompare [ ++ compareIndex ] ) ==
72
+ queryWithoutCase [ currentQueryIndex ] )
73
+ || ( char . IsNumber ( c ) && c == queryWithoutCase [ currentQueryIndex ] ) :
74
+ acronymMatchData . Add ( map ? . MapToOriginalIndex ( compareIndex ) ?? compareIndex ) ;
89
75
currentQueryIndex ++ ;
90
76
continue ;
91
77
92
- case char c when char . IsWhiteSpace ( c ) :
78
+ case var c when char . IsWhiteSpace ( c ) :
93
79
compareIndex ++ ;
94
80
acronymScore -= 10 ;
95
81
break ;
96
- case char c when char . IsUpper ( c ) || char . IsNumber ( c ) :
82
+ case var c when char . IsUpper ( c ) || char . IsNumber ( c ) :
97
83
acronymScore -= 10 ;
98
84
break ;
99
85
}
@@ -105,7 +91,7 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
105
91
var fullStringToCompareWithoutCase = opt . IgnoreCase ? stringToCompare . ToLower ( ) : stringToCompare ;
106
92
107
93
108
- var querySubstrings = queryWithoutCase . Split ( new [ ] { ' ' } , StringSplitOptions . RemoveEmptyEntries ) ;
94
+ var querySubstrings = queryWithoutCase . Split ( new [ ] { ' ' } , StringSplitOptions . RemoveEmptyEntries ) ;
109
95
int currentQuerySubstringIndex = 0 ;
110
96
var currentQuerySubstring = querySubstrings [ currentQuerySubstringIndex ] ;
111
97
var currentQuerySubstringCharacterIndex = 0 ;
@@ -120,17 +106,19 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
120
106
var indexList = new List < int > ( ) ;
121
107
List < int > spaceIndices = new List < int > ( ) ;
122
108
123
- for ( var compareStringIndex = 0 ; compareStringIndex < fullStringToCompareWithoutCase . Length ; compareStringIndex ++ )
109
+ for ( var compareStringIndex = 0 ;
110
+ compareStringIndex < fullStringToCompareWithoutCase . Length ;
111
+ compareStringIndex ++ )
124
112
{
125
-
126
113
// To maintain a list of indices which correspond to spaces in the string to compare
127
114
// To populate the list only for the first query substring
128
115
if ( fullStringToCompareWithoutCase [ compareStringIndex ] . Equals ( ' ' ) && currentQuerySubstringIndex == 0 )
129
116
{
130
117
spaceIndices . Add ( compareStringIndex ) ;
131
118
}
132
119
133
- if ( fullStringToCompareWithoutCase [ compareStringIndex ] != currentQuerySubstring [ currentQuerySubstringCharacterIndex ] )
120
+ if ( fullStringToCompareWithoutCase [ compareStringIndex ] !=
121
+ currentQuerySubstring [ currentQuerySubstringCharacterIndex ] )
134
122
{
135
123
matchFoundInPreviousLoop = false ;
136
124
continue ;
@@ -154,14 +142,16 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
154
142
// in order to do so we need to verify all previous chars are part of the pattern
155
143
var startIndexToVerify = compareStringIndex - currentQuerySubstringCharacterIndex ;
156
144
157
- if ( AllPreviousCharsMatched ( startIndexToVerify , currentQuerySubstringCharacterIndex , fullStringToCompareWithoutCase , currentQuerySubstring ) )
145
+ if ( AllPreviousCharsMatched ( startIndexToVerify , currentQuerySubstringCharacterIndex ,
146
+ fullStringToCompareWithoutCase , currentQuerySubstring ) )
158
147
{
159
148
matchFoundInPreviousLoop = true ;
160
149
161
150
// if it's the beginning character of the first query substring that is matched then we need to update start index
162
151
firstMatchIndex = currentQuerySubstringIndex == 0 ? startIndexToVerify : firstMatchIndex ;
163
152
164
- indexList = GetUpdatedIndexList ( startIndexToVerify , currentQuerySubstringCharacterIndex , firstMatchIndexInWord , indexList ) ;
153
+ indexList = GetUpdatedIndexList ( startIndexToVerify , currentQuerySubstringCharacterIndex ,
154
+ firstMatchIndexInWord , indexList ) ;
165
155
}
166
156
}
167
157
@@ -174,11 +164,13 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
174
164
if ( currentQuerySubstringCharacterIndex == currentQuerySubstring . Length )
175
165
{
176
166
// if any of the substrings was not matched then consider as all are not matched
177
- allSubstringsContainedInCompareString = matchFoundInPreviousLoop && allSubstringsContainedInCompareString ;
167
+ allSubstringsContainedInCompareString =
168
+ matchFoundInPreviousLoop && allSubstringsContainedInCompareString ;
178
169
179
170
currentQuerySubstringIndex ++ ;
180
171
181
- allQuerySubstringsMatched = AllQuerySubstringsMatched ( currentQuerySubstringIndex , querySubstrings . Length ) ;
172
+ allQuerySubstringsMatched =
173
+ AllQuerySubstringsMatched ( currentQuerySubstringIndex , querySubstrings . Length ) ;
182
174
if ( allQuerySubstringsMatched )
183
175
break ;
184
176
@@ -188,13 +180,16 @@ public MatchResult FuzzyMatch(string query, string stringToCompare, MatchOption
188
180
}
189
181
}
190
182
183
+
191
184
// proceed to calculate score if every char or substring without whitespaces matched
192
185
if ( allQuerySubstringsMatched )
193
186
{
194
187
var nearestSpaceIndex = CalculateClosestSpaceIndex ( spaceIndices , firstMatchIndex ) ;
195
- var score = CalculateSearchScore ( query , stringToCompare , firstMatchIndex - nearestSpaceIndex - 1 , lastMatchIndex - firstMatchIndex , allSubstringsContainedInCompareString ) ;
188
+ var score = CalculateSearchScore ( query , stringToCompare , firstMatchIndex - nearestSpaceIndex - 1 ,
189
+ lastMatchIndex - firstMatchIndex , allSubstringsContainedInCompareString ) ;
196
190
197
- return new MatchResult ( true , UserSettingSearchPrecision , indexList , score ) ;
191
+ var resultList = indexList . Distinct ( ) . Select ( x => map ? . MapToOriginalIndex ( x ) ?? x ) . ToList ( ) ;
192
+ return new MatchResult ( true , UserSettingSearchPrecision , resultList , score ) ;
198
193
}
199
194
200
195
return new MatchResult ( false , UserSettingSearchPrecision ) ;
@@ -209,14 +204,15 @@ private int CalculateClosestSpaceIndex(List<int> spaceIndices, int firstMatchInd
209
204
}
210
205
else
211
206
{
212
- int ? ind = spaceIndices . OrderBy ( item => ( firstMatchIndex - item ) ) . Where ( item => firstMatchIndex > item ) . FirstOrDefault ( ) ;
207
+ int ? ind = spaceIndices . OrderBy ( item => ( firstMatchIndex - item ) )
208
+ . FirstOrDefault ( item => firstMatchIndex > item ) ;
213
209
int closestSpaceIndex = ind ?? - 1 ;
214
210
return closestSpaceIndex ;
215
211
}
216
212
}
217
213
218
214
private static bool AllPreviousCharsMatched ( int startIndexToVerify , int currentQuerySubstringCharacterIndex ,
219
- string fullStringToCompareWithoutCase , string currentQuerySubstring )
215
+ string fullStringToCompareWithoutCase , string currentQuerySubstring )
220
216
{
221
217
var allMatch = true ;
222
218
for ( int indexToCheck = 0 ; indexToCheck < currentQuerySubstringCharacterIndex ; indexToCheck ++ )
@@ -231,7 +227,8 @@ private static bool AllPreviousCharsMatched(int startIndexToVerify, int currentQ
231
227
return allMatch ;
232
228
}
233
229
234
- private static List < int > GetUpdatedIndexList ( int startIndexToVerify , int currentQuerySubstringCharacterIndex , int firstMatchIndexInWord , List < int > indexList )
230
+ private static List < int > GetUpdatedIndexList ( int startIndexToVerify , int currentQuerySubstringCharacterIndex ,
231
+ int firstMatchIndexInWord , List < int > indexList )
235
232
{
236
233
var updatedList = new List < int > ( ) ;
237
234
@@ -252,7 +249,8 @@ private static bool AllQuerySubstringsMatched(int currentQuerySubstringIndex, in
252
249
return currentQuerySubstringIndex >= querySubstringsLength ;
253
250
}
254
251
255
- private static int CalculateSearchScore ( string query , string stringToCompare , int firstIndex , int matchLen , bool allSubstringsContainedInCompareString )
252
+ private static int CalculateSearchScore ( string query , string stringToCompare , int firstIndex , int matchLen ,
253
+ bool allSubstringsContainedInCompareString )
256
254
{
257
255
// A match found near the beginning of a string is scored more than a match found near the end
258
256
// A match is scored more if the characters in the patterns are closer to each other,
@@ -347,7 +345,7 @@ public bool IsSearchPrecisionScoreMet()
347
345
348
346
private bool IsSearchPrecisionScoreMet ( int rawScore )
349
347
{
350
- return rawScore >= ( int ) SearchPrecision ;
348
+ return rawScore >= ( int ) SearchPrecision ;
351
349
}
352
350
353
351
private int ScoreAfterSearchPrecisionFilter ( int rawScore )
@@ -360,4 +358,4 @@ public class MatchOption
360
358
{
361
359
public bool IgnoreCase { get ; set ; } = true ;
362
360
}
363
- }
361
+ }
0 commit comments