/// <summary> /// Call this method to compute the value of /// FilterDispertionLevel, FilterFullyMatch, FilterMatchedRanges /// </summary> /// <param name="lowerCaseFilterString"></param> public void FilterApply(string lowerCaseFilterString) { FilterMatchedRanges = new List <CharacterRange>(); FilterFullyMatch = true; FilterDispertionLevel = 0; if (string.IsNullOrEmpty(lowerCaseFilterString) || string.IsNullOrEmpty(DisplayText)) { return; } var lcText = DisplayText.ToLower(); var textLenght = lcText.Length; var filterLenght = lowerCaseFilterString.Length; int pos = 0; int posFilter = 0; bool matching = false; int startMatch = 0; while (pos < textLenght) { // remember matching state at the beginning of the loop bool wasMatching = matching; // we match the current char of the filter if (lcText[pos] == lowerCaseFilterString[posFilter]) { if (!matching) { matching = true; startMatch = pos; } posFilter++; // we matched the entire filter if (posFilter >= filterLenght) { FilterMatchedRanges.Add(new CharacterRange(startMatch, pos - startMatch + 1)); break; } } else { matching = false; // gap between match mean more penalty than finding the match later in the string if (posFilter > 0) { FilterDispertionLevel += 900; } else { FilterDispertionLevel += 30; } } // we stopped matching, remember matching range if (!matching && wasMatching) { FilterMatchedRanges.Add(new CharacterRange(startMatch, pos - startMatch)); } pos++; } // put the exact matches first if (filterLenght != textLenght) { FilterDispertionLevel += 1; } // we reached the end of the input, if we were matching stuff, remember matching range if (pos >= textLenght && matching) { FilterMatchedRanges.Add(new CharacterRange(startMatch, pos - 1 - startMatch)); } // we didn't match the entire filter if (posFilter < filterLenght) { FilterFullyMatch = false; } }