Nauman Sharif
Nauman Sharif

Reputation: 205

C# Compare one List string with substring of other list string

I have two lists

List<string> ingoreEducationKeywords= new List<string>(){"Uni", "School", "College",}; 
List<string> userEducation= new List<string>(){"MCS", "BCS", "School of Arts","College of Medicine"}; 

Now I want to get a list which has no substring from the ignore list.

require list {"MCS", "BCS"}

Upvotes: 1

Views: 1793

Answers (4)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726559

That's a relatively straightforward query that can be constructed with Any or All, depending on your preferences:

var res = userEducation
    .Where(s => !ingoreEducationKeywords.Any(ignored => s.Contains(ignored)))
    .ToList();

or

var res = userEducation
    .Where(s => ingoreEducationKeywords.All(ignored => !s.Contains(ignored)))
    .ToList();

If the lists are very large, you could improve performance by using regex to match all words simultaneously:

var regex = new Regex(
    string.Join("|", ingoreEducationKeywords.Select(Regex.Escape))
);
var res = userEducation.Where(s => !regex.IsMatch(s)).ToList();

Demo.

Upvotes: 8

Patrick Hofman
Patrick Hofman

Reputation: 156968

You can use Where, Any and Contains:

var list = userEducation.Where(ed => !ingoreEducationKeywords.Any(ik => ed.Contains(ik)));

It searches all occurences in userEducation where the education does not have any match in ingoreEducationKeywords.

Upvotes: 3

user2960398
user2960398

Reputation: 383

List<string> ingoreEducationKeywords = new List<string>() { "Uni", "School", "College", };
List<string> userEducation = new List<string>() { "MCS", "BCS", "School of Arts", "College of Medicine" };

var result = userEducation.Where(r => !ingoreEducationKeywords.Any(t => r.Contains(t))).ToList();

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500465

It's a matter of phrasing what you want in a way that leads to a natural translation into LINQ:

  • You want items from userEducation (that suggests you'll start with userEducation)
  • Where none of ignoreEducationKeywords are substrings.
    • "None" is equivalent to "not any"
    • To check for substrings you can use Contains

That leads to:

var query = userEducation
   .Where(candidate => !ignoredKeyWords.Any(ignore => candidate.Contains(ignore)));

The same thought process can help in many other queries.

Another option would be to create your own None extension method, assuming you're using LINQ to Objects:

public static class Extensions
{
    public static bool None(this IEnumerable<T> source, Func<T, bool> predicate)
        => !source.Any(predicate);
}

Then you could rewrite the query without the negation:

var query = userEducation
   .Where(candidate => ignoredKeyWords.None(ignore => candidate.Contains(ignore)));

Upvotes: 6

Related Questions