27

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.

2
  • 2
    So is x.tags a list too? Commented May 20, 2014 at 15:40
  • Could you give some sample input and output? It's likely that you'll want to use PredicateBuilder, but the "know how many of the items were matched" might further complicate things. Commented May 20, 2014 at 15:44

6 Answers 6

32

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).

Sign up to request clarification or add additional context in comments.

10 Comments

Does this still apply if tags is a string?
No, you'd need to change it - I was assuming that as tags is plural, it's a collection of tags. Why is it called "tags" if it's a single value? Or is it a comma-separated value? That would make things more complicated.
Its a string of comma separated values. Was hoping to be able to just check to see if any of the stings in the list were anywhere in the string of , separated values.
@Lrayh: how did you expect us to guess that that's what you meant? And is this EF, Linq to Sql, something else?
Sorry, I didn't think of it when I first created the question. Using EF. Added that part to the original question earlier.
|
8

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)));

2 Comments

what is y? where did you define that? Isn't X the search term you're looking for?
@softwareisfun that's a lambda function. query has items, and therefore x is a query item. mylist has items, therefore y is a mylist item. Check out the .Where and .Any extensions for in Linq library. Thanks aleonj, this is great ^
2

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)

Comments

1

like this:

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

 var result = query.Where(x => list.Contains(x.tags));

3 Comments

Contains does not accept a sequences of items as it's parameter
the OP states that x.tags is a string, although I am still unsure of the question
This works if x.tags matches exactly to the list. How about if I want to have the LIKE effect? Said will return as long as tags is "One milk", "One fridge"... Currently it will only return if the tags is "One".
1
  var t = new List<string> { "a", "b", "c" };

var y = "a b d";

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

1 Comment

No, I'm pretty certain this is not what the OP is asking for.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.