Public Class FuzzySearch
'Searches with the options passed to it. Returns the results
Public Shared Function Search(ByVal Options As SearchOptions) As SearchResults
'Creates an array to store the results as they come in. As percentages
Dim Percentages(Options.List.Count) As Double
'Two loops. First we loop through each word (Separated by a space). Next we search each item with the
'search term. If we have a match then we add to the percentage for that item.
For Each SearchTerm As String In Options.SearchString.Split(" "c)
For i As Integer = 0 To Options.List.Count - 1
Dim Item As String = CStr(Options.List(i))
If Item.IndexOf(SearchTerm) <> -1 Then
Percentages(i) += SearchTerm.Length / Item.Length
End If
Next
Next
'All we are doing here is finding the index of the highest percentage.
Dim HighestPercentageIndex As Integer, HighestPercentageValue As Double
HighestPercentageIndex = -1
HighestPercentageValue = -1
For i As Integer = 0 To Percentages.GetUpperBound(0)
If Percentages(i) > HighestPercentageValue Then
HighestPercentageIndex = i
HighestPercentageValue = Percentages(i)
End If
Next
'Finally we determine whether the highest percentage meets the thresold.
If HighestPercentageValue >= Options.SearchThresold Then
Return New SearchResults(HighestPercentageIndex, CStr(Options.List(HighestPercentageIndex)), HighestPercentageValue, Options)
Else
Return New SearchResults(-1, "Not Found", -1, Options)
End If
End Function
End Class
'Search options structure. Passed to search function
Public Structure SearchOptions
Private _SearchString As String
Private _List As IList
Private _SearchThresold As Double
'The SearchString must contain an actual search (No Null or empty values)
'The List must be valid (Not Null or empty)
'The SearchThresold must be between 0 and 1 (Percentage)
Public Sub New(ByVal SearchString As String, ByVal List As IList, ByVal SearchThresold As Double)
If SearchString Is Nothing OrElse SearchString.Trim.Length = 0 Then Throw New ArgumentException("Search String cannot be null or empty", "SearchString")
If List Is Nothing OrElse List.Count = 0 Then Throw New ArgumentException("List cannot be null or empty", "List")
If SearchThresold < 0 Or SearchThresold > 1 Then Throw New ArgumentException("Search Thresold must be between 0 and 1", "SearchThresold")
_SearchString = SearchString
_List = List
_SearchThresold = SearchThresold
End Sub
'Readonly properties
Public ReadOnly Property SearchString() As String
Get
Return _SearchString
End Get
End Property
Public ReadOnly Property List() As IList
Get
Return _List
End Get
End Property
Public ReadOnly Property SearchThresold() As Double
Get
Return _SearchThresold
End Get
End Property
End Structure
'Results Structure. Returned by the Search function
Public Structure SearchResults
Private _Index As Integer
Private _Value As String
Private _Relevance As Double
Private _SearchOptions As SearchOptions
Public Sub New(ByVal Index As Integer, ByVal Value As String, ByVal Relevance As Double, ByVal SearchOptions As SearchOptions)
_Index = Index
_Value = Value
_Relevance = Relevance
_SearchOptions = SearchOptions
End Sub
'Readonly properties
Public ReadOnly Property Index() As Integer
Get
Return _Index
End Get
End Property
Public ReadOnly Property Value() As String
Get
Return _Value
End Get
End Property
Public ReadOnly Property Relevance() As Double
Get
Return _Relevance
End Get
End Property
Public ReadOnly Property SearchOptions() As SearchOptions
Get
Return _SearchOptions
End Get
End Property
End Structure