hunterex
hunterex

Reputation: 595

How to check if a substring is found in a list of string

I have a Dictionary whose key values (string type) are as below:

I also have a List(Of String) which contains:

I want to delete any entry in the Dictionary where any value in the List is a substring of the Dictionary item's key.

In the example above, the entries with the following keys will be removed from the Dictionary:

How do I filter and delete those entries from the Dictionary without multiple loops?

Here is the sample code/pseudocode I have tried:

For Each whatKVP In whatDict
    If IsSubstringFoundInAList(whatKVP.Key, listName) = True Then
        listKeyDel.Add(whatKVP.Key)
    End If
Next

For Each whatKey In listKeyDel
    whatDict.Remove(whatKey)
Next

Private Function IsSubstringFoundInAList(ByVal strIp As String, ByVal listStr As List(Of String)) As Boolean 
    Dim whatStr As String

    For Each whatStr In listStr
        If strIp.Contains(whatStr) = True Then
            Return True
        End If
    Next

    Return False
End Function

In the code above, I need to use many (3) loops to complete the task. Is there any better way/neater code to complete it?

Upvotes: 1

Views: 711

Answers (4)

Keith Aymar
Keith Aymar

Reputation: 924

You would need something like this. I used 'StartsWith' but you can change to 'Contains'

    Dim outList As New List(Of String)
    outList.Add("mark")
    outList.Add("apple")

    whatDict = whatDict.Where(Function(x) Not outList.Exists(Function(y) x.Key.StartsWith(y))).ToDictionary(Function(x) x.Key, Function(x) x.Value)

Upvotes: 1

Quima
Quima

Reputation: 914

This function should do the trick:

Public Function FilterDictionary(Of T, K)(Dictionary As IDictionary(Of T, K), FilterList As ICollection(Of T)) As IDictionary(Of T, k)
    Return (From Item In Dictionary
            Where Not FilterList.Any(Function(x) Item.Key.ToString.Contains(x.ToString))).
            ToDictionary(Function(x) x.Key, Function(x) x.Value)
End Function

Usage:

Dim MyDictionary As New Dictionary(Of String, Integer)
Dim FilterList As New List(Of String)
'Fill Collections...
Dim FilteredDictionary = FilterDictionary(MyDictionary, FilterList)

Upvotes: 0

Blackwood
Blackwood

Reputation: 4534

You can do this in a single statement. The following assumes that whatDict is your dictionary and listName is your list of key substrings.

whatDict = whatDict.Where(Function(kvp) Not listName.Any(Function(n) kvp.Key.Contains(n))) _
    .ToDictionary(Function(kvp) kvp.Key, Function(kvp) kvp.Value)

This creates a new Dictionary containing only the KeyValuePairs from the existing Dictionary where the key does not contain any of the substrings in listName.

Upvotes: 1

doom87er
doom87er

Reputation: 468

You can use List.Any() looks much cleaner in my opinion

Dim findString = "foo"
listOfString.Any(Function(stringInList)
        Return stringInList.Equals(findString)
    End Function)

if your looking for performance though, id suggest using Linq

Upvotes: 1

Related Questions