Check if a string contains an element from a list (of strings)

308,227

Solution 1

With LINQ, and using C# (I don't know VB much these days):

bool b = listOfStrings.Any(s=>myString.Contains(s));

or (shorter and more efficient, but arguably less clear):

bool b = listOfStrings.Any(myString.Contains);

If you were testing equality, it would be worth looking at HashSet etc, but this won't help with partial matches unless you split it into fragments and add an order of complexity.


update: if you really mean "StartsWith", then you could sort the list and place it into an array ; then use Array.BinarySearch to find each item - check by lookup to see if it is a full or partial match.

Solution 2

when you construct yours strings it should be like this

bool inact = new string[] { "SUSPENDARE", "DIZOLVARE" }.Any(s=>stare.Contains(s));

Solution 3

I liked Marc's answer, but needed the Contains matching to be CaSe InSenSiTiVe.

This was the solution:

bool b = listOfStrings.Any(s => myString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))

Solution 4

There were a number of suggestions from an earlier similar question "Best way to test for existing string against a large list of comparables".

Regex might be sufficient for your requirement. The expression would be a concatenation of all the candidate substrings, with an OR "|" operator between them. Of course, you'll have to watch out for unescaped characters when building the expression, or a failure to compile it because of complexity or size limitations.

Another way to do this would be to construct a trie data structure to represent all the candidate substrings (this may somewhat duplicate what the regex matcher is doing). As you step through each character in the test string, you would create a new pointer to the root of the trie, and advance existing pointers to the appropriate child (if any). You get a match when any pointer reaches a leaf.

Solution 5

Old question. But since VB.NET was the original requirement. Using the same values of the accepted answer:

listOfStrings.Any(Function(s) myString.Contains(s))
Share:
308,227

Related videos on Youtube

user57175
Author by

user57175

Updated on May 20, 2021

Comments

  • user57175
    user57175 almost 3 years

    For the following block of code:

    For I = 0 To listOfStrings.Count - 1
        If myString.Contains(lstOfStrings.Item(I)) Then
            Return True
        End If
    Next
    Return False
    

    The output is:

    Case 1:

    myString: C:\Files\myfile.doc
    listOfString: C:\Files\, C:\Files2\
    Result: True
    

    Case 2:

    myString: C:\Files3\myfile.doc
    listOfString: C:\Files\, C:\Files2\
    Result: False
    

    The list (listOfStrings) may contain several items (minimum 20) and it has to be checked against a thousands of strings (like myString).

    Is there a better (more efficient) way to write this code?

  • tvanfosson
    tvanfosson over 15 years
    Instead of Contains I'd use StartsWith based on his examples.
  • Marc Gravell
    Marc Gravell over 15 years
    @tvanfosson - that depends on whether the examples are fully inclusive, but yes, I'd agree. Simple to change, of course.
  • Torsten Marek
    Torsten Marek over 15 years
    In how far is this code more efficient on the algorithmic level? It's shorter and faster if the loops in "Any" are faster, but the problem that you have to perform exact matching many times is the same.
  • Craig van Wilson
    Craig van Wilson over 15 years
    You could setup a custom comparator if you are using a set.
  • ICR
    ICR over 15 years
    The second isn't really more efficient by any measurable difference in practice.
  • Marc Gravell
    Marc Gravell over 15 years
    @ICR - there isn't a huge amount you can (easily) do for contains matching. If it is "starts with", I've added a comment re binary search - that would be faster.
  • Marc Gravell
    Marc Gravell over 15 years
    Re starts-with; perhaps pre-sort and use binary search? That might be faster again.
  • ca9163d9
    ca9163d9 over 11 years
    Why the later one is more efficient than the lambda one?
  • Marc Gravell
    Marc Gravell over 11 years
    @NickW do you mean the middle one? The first one creates a delegate to an anonymous method on a capture-context with a reference to myString which then invokes the string.Contains method on the myString field. The second one simply creates a delegate to the string.Contains method with myString as the target for the delegate - much more direct.
  • Connell
    Connell almost 9 years
    I find putting this in an extension method with params keyword for the array makes it much more readable. myString.ContainsAny("this", "that", "those");.
  • CSharped
    CSharped almost 8 years
    Shouldn't it be >-1 ?
  • WhoIsRich
    WhoIsRich almost 8 years
    @CSharped Doesn't matter as >-1 ( more than minus 1 ) and >=0 ( more or equal to zero ) are the same thing.
  • kirushan
    kirushan about 7 years
    How do you figure out which value has matched ? When i passed S to get the value I get a build error.
  • Jumabek Alikhanov
    Jumabek Alikhanov almost 7 years
    @MarcGravell What is the running time complexity?