private string PrepareQuery(FindMatchingOrganisations query) { var returnString = query.CompanyName.Trim().ToUpperInvariant(); foreach (var specialCase in specialCases) { specialCase.CleanseSpecialCases(ref returnString); } return(returnString); }
public async Task <IList <OrganisationData> > HandleAsync(FindMatchingOrganisations query) { var searchTerm = PrepareQuery(query); // This search uses the Levenshtein edit distance as a search algorithm. var permittedDistance = CalculateMaximumLevenshteinDistance(searchTerm); var possibleOrganisations = await GetPossibleOrganisationNames(searchTerm); var uppercaseOrganisationNames = possibleOrganisations.Select(o => new KeyValuePair <string, Guid>(o.Name.ToUpperInvariant(), o.Id)) .ToArray(); // Special cases should be ignored when counting the distance. This loop replaces special cases with string.Empty. for (var i = 0; i < possibleOrganisations.Length; i++) { foreach (var specialCase in specialCases) { specialCase.CleanseSpecialCases(ref uppercaseOrganisationNames[i]); } } var matchingIdsWithDistance = new List <KeyValuePair <Guid, int> >(); for (var i = 0; i < possibleOrganisations.Length; i++) { var distance = StringSearch.CalculateLevenshteinDistance(searchTerm, uppercaseOrganisationNames[i].Key); if (distance <= permittedDistance) { matchingIdsWithDistance.Add(new KeyValuePair <Guid, int>(uppercaseOrganisationNames[i].Value, distance)); } } matchingIdsWithDistance = matchingIdsWithDistance.OrderBy(m => m.Value).ToList(); var matchingOrganisations = matchingIdsWithDistance.Select( m => possibleOrganisations.Single(o => o.Id == m.Key)); return(matchingOrganisations.Select(o => new OrganisationData { Id = o.Id, Name = o.Name }).ToList()); }