简体   繁体   中英

How to use Linq to check if a list of strings contains any string in a list

I'm constructing a linq query that will check is a string in the DB contains any of the strings in a list of strings.

Something like.

query = query.Where(x => x.tags
                   .Contains(--any of the items in my list of strings--));

I'd also like to know how many of the items in the list were matched.

Any help would be appreciated.

Update: I should have mentioned that tags is a string not a list. And I am adding on a couple more wheres that are not related to tags before the query actually runs. This is running against entity framework.

EDIT: This answer assumed that tags was a collection of strings...

It sounds like you might want:

var list = new List<string> { ... };
var query = query.Where(x => x.tags.Any(tag => list.Contains(tag));

Or:

var list = new List<string> { ... };
var query = query.Where(x => x.tags.Intersect(list).Any());

(If this is using LINQ to SQL or EF, you may find one works but the other doesn't. In just LINQ to Objects, both should work.)

To get the count, you'd need something like:

var result = query.Select(x => new { x, count = x.tags.Count(tag => list.Contains(tag)) })
                  .Where(pair => pair.count != 0);

Then each element of result is a pair of x (the item) and count (the number of matching tags).

I've done something like this before:

var myList = new List<string>();
myList.Add("One");
myList.Add("Two");

var matches = query.Where(x => myList.Any(y => x.tags.Contains(y)));

I am not quite sure from your question if x.tags is a string or list, if it is a list Jon Skeet's answer is correct. If I understand you correctly though x.tags is a string of strings. If so then the solution is:

list.Any(x => x.tags.IndexOf(x) > -1)

to count them do

list.Count(x => x.tags.IndexOf(x) > -1)

like this:

List<string> list = new List<string>();
list.Add("One");
list.Add("Two");

 var result = query.Where(x => list.Contains(x.tags));
  var t = new List<string> { "a", "b", "c" };

var y = "abd";

var res = y.Count(x => t.Contains(x.ToString()));

I faced a similar problem recently and here's how I managed to work it out:

var list = [list of strings];
if (list != null && list.Any())
{
    queryable = queryable.Where(x => x.tags != null);
    var tagQueries = new List<IQueryable<WhateverTheDbModelIs>>();
    foreach (var element in list)
    {
        tagQueries.Add(queryable.Where(x => x.tags.Contains(element)));
    }
    IQueryable<WhateverTheDbModelIs> query = tagQueries.FirstOrDefault();
    foreach (var tagQuery in tagQueries)
    {
        query = query.Union(tagQuery);
    }
    queryable = queryable.Intersect(query);
}

probably not the best option but something a less experienced developer can understand and use

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