简体   繁体   中英

How to check if list contains all string of another list

I have a object list. That object contains a string List. Like that:

public class ObjectA
{
    ...
    IList<string> StringList;
}

And I have a list of words to search on StringList. I need to search on a ObjectA list, and find all ObjectA that have all words (parts of all words).

So I did that:

 List<ObjectA> myObjectList;
 List<string> wordsToFind;  

 var result = myObjectList.Where(objectA => wordsToFind.All(objectA.StringList.Contains));

The problem is my result is getting only whole words (equals). I would like to get results that contains parts of my wordsToFind.

Example

wordsToFind = {"tes","don"};
StringListElement = {"test", "done"}

Should return on my select.

How can I do that?

IndexOf is probably where you want to be, or one of its overloads

Reports the zero-based index of the first occurrence of a specified Unicode character or string within this instance. The method returns -1 if the character or string is not found in this instance.

List<ObjectA> myObjectList;
List<string> wordsToFind;  

var result = myObjectList.Where(x => x.StringList.All(y => wordsToFind.Any(z => y.IndexOf(z) >= 0)));

Also note the time complexity of this is atrocious


Update

Full Demo Here

Also note, if you want case insensitivity use

y.IndexOf(z, StringComparison.InvariantCultureIgnoreCase) 

or one of the following

  • CurrentCulture Compare strings using culture-sensitive sort rules and the current culture.

  • CurrentCultureIgnoreCase Compare strings using culture-sensitive sort rules, the current culture, and ignoring the case of the strings being compared.

  • InvariantCulture Compare strings using culture-sensitive sort rules and the invariant culture.

  • InvariantCultureIgnoreCase Compare strings using culture-sensitive sort rules, the invariant culture, and ignoring the case of the strings being compared.

  • Ordinal Compare strings using ordinal (binary) sort rules.

  • OrdinalIgnoreCase Compare strings using ordinal (binary) sort rules and ignoring the case of the strings being compared.

I think this should work for you

var wordsToFind = new List<string>{ "tes","don"};
var data= new List<ObjectA>()
{
    new ObjectA()
    {
        StringList = new List<string>{"test", "done", "blah"}
    },
    new ObjectA()
    {
        StringList = new List<string>{"test2", "done2", "blah2"}
    }
};

var result = (from item in data.Select(x => x.StringList)
              from bar in item
              from word in wordsToFind
              where bar.Contains(word)
              select bar)
              .ToList();

The result should give you

"test", "done","test2", "done2"

The ways to do this is by using a combination of Any and All .

You need to check if all the elements of wordsToFind are substring of any elements in StringList

bool result = wordsToFind.All(word => currentObject.StringList.Any(str => str.Contains(word));

This is for one object out of the list of Objects. You can again apply All to that list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM