I have two list:
List of strings:
var keywords = _db.KeyWords.Select(k => k.Word);
and list of objects:
var articles = _db.Articles;
What I want to achieve is to filter articles where article properties contains keywords, for example:
var model = articles.Where(a => a.Title.Contains(keywords) || a.Description.Contains(keywords));
Is possible in one query without foreach loop?
One solution is :
List<Article> model = new List<Article>();
foreach (var keyword in keywords)
{
model.AddRange(articles.Where(a => a.Title.Contains(keyword) || a.Description.Contains(keyword)));
}
But i have 100 keywords, and it is heavy process using foreach loop.
In words, you need to take only those items which have any word from keywords
. So, in LINQ it can be done with something like:
var model = articles
.Where(a => keywords.Any(k => a.Title.Contains(k) || a.Description.Contains(k)))
.ToList();
If title or description does not contain any word from keywords
, then it will not be added in the resulted list.
Note that it will not improve time complexity compared with foreach
, but it may improve readbility.
In general, any algorithm iterating through all the keywords and articles, is going to take approximately Number of articles * Number of keywords * Average length of article
operations, which grows pretty fast when variables grow. Keep it in mind.
You can do this using the Any
extension method.
For your solution:
var model = articles
.Where(a => !keywords.Any(k => a.Title.Contains(k) || a.Description.Contains(k)))
.ToList();
Here is a basic example to understand the method:
public class Person
{
public string Name { get; set; }
public string Pet { get; set; }
}
List<string> animals = new List<string>();
animals.Add("donkey");
animals.Add("horse");
List<Person> people = new List<Person>();
people.Add(new Person()
{
Name = "Marco",
Pet = "horse"
});
people.Add(new Person()
{
Name = "John",
Pet = "donkey"
});
people.Add(new Person()
{
Name = "Penny",
Pet = "dog"
});
//result will only include people who have pets that are in the animal list.
var res = people.Where(p => animals.Any(a => p.Pet.Contains(a)));
foreach (var item in res)
{
Console.WriteLine("{0}-{1}", item.Name, item.Pet);
}
Console.ReadLine();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With