Richard Steele
Richard Steele

Reputation: 115

Check if a string contains all other strings

I am trying to code a part of a software where I try to show the results that match search criteria.

I have a textbox where I can type one or more words I want to search and a listview that contains 4 different columns and a dozen rows. The idea is that each listview row contains lots of words and I want to see only the rows that contain all the words I have typed in the textbox. I have finished the code that searches for one term only. The problem I am having is that I don't fully understand how to do the same, but using multiple terms instead of one term only.

In the textbox, I write the words I want to search separated by a space. I have a variable where I keep the whole content of the listview row separated by : (example => col1row1content:col1row2content:col1row3content,etc). Summarizing, I want to check if a string (the full content of a row) contains all other strings (each word I have typped in the textbox).

This is the code I have implemented:

Dim textboxFullContentArray As String() = textboxSearch.Split(New Char() {" "c})
Dim Content As String
Dim containsAll As Boolean = False
Dim wholeRowContent(listviewMain.Items.Count - 1) As String ' each index of the array keeps the entire row content (one array contains all 4 cells of the row)



' wholeRowContent contains in one index the entire content of a row. That means, 
' the index contains the 4 cells that represent an entire row. 
' The format is like "rowData1:rowData2:rowData3:rowData4" (omitted for simplicity)
    For Q As Integer = 0 To listviewMain.Items.Count - 1
        For Each Content In textboxFullContentArray
            If wholeRowContent(Q).ToLower.Contains(Content) Then
                containsAll = True
                ' rest of the code...
            ElseIf Not wholeRowContent(Q).ToLower.Contains(Content) Then
                containsAll = False
                Exit For
            End If
        Next
    Next

But of course, this code is showing false positives and I think it's not a good solution. I think it must be much easier and I am overcomplicating the concept.

I am using VB.Net 2013

Upvotes: 0

Views: 592

Answers (3)

Richard Steele
Richard Steele

Reputation: 115

After some hours looking for a simple and effective solution (and trying different codes), I have finally found this solution that I adapted from: Bad word filter - stackoverflow

For Q As Integer = 0 To listviewMain.Items.Count - 1
    If textboxFullContentArray.All(Function(b) wholeRowContent(q).ToLower().Contains(b.ToLower())) Then
    ' my code
    End If
Next

Upvotes: 0

jmcilhinney
jmcilhinney

Reputation: 54417

You can determine whether a String contains all of a list of substrings with a single line of code:

If substrings.All(Function(s) str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0) Then

Notice that I have actually implemented a case-insensitive comparison, rather than using ToLower or ToUpper.

It may not seem as neat to call IndexOf rather than Contains but guess what: Contains actually calls IndexOf internally anyway:

public bool Contains(string value)
{
    return this.IndexOf(value, StringComparison.Ordinal) >= 0;
}

You can write your own extension methods if you want a case-insensitive Contains method:

<Extension>
Public Function Contains(source As String,
                         value As String,
                         comparisonType As StringComparison) As Boolean
    Return source.IndexOf(value, comparisonType) >= 0
End Function

Upvotes: 3

Alexandra
Alexandra

Reputation: 413

Your If/Else looks like it could be simplified. I would set your containsAll value to true outside the nested loops, and only if you encounter a "Content" in "textboxFullContentArray" that is not contained in wholeRowContent(Q) you set containsAll to false, otherwise do nothing.

Also, one way to see what's going on is to print statements with the values that are being compared throughout your function, which you can read through and see what is happening at runtime when the false positives occur.

Upvotes: 0

Related Questions