简体   繁体   中英

Using LINQ to get a list of items where the item contains a part of an item from another list

Having a list of models:

List<string> models = new List<string>
{
    "abcd1234",
    "xycd9999",
    "zzz999z",
    "ros7777"
};

Having a filterer list:

List<string> filterer = new List<string>
    {
        "cd",
        "9999"
    };

I am trying using LINQ to get all the models that contains as part of their name the filterer items.

For this example:

  1. "abcd1234" and "xycd9999" contains "cd"
  2. "xycd9999" contains "9999"

therefore the LINQ operation will return a list of the two items: "abcd1234" and "xycd9999".

var filteredList = models
                   .Where(m => m.Contains("/*HERE WILL BE THE FILTERER ITEMS*/"))
                   .Distinct()
                   .ToList(); 

What is the correct syntax?

var filteredList = models
    .Where(x => filterer.Any(y => x.Contains(y))
    .ToList();

Distinct serves no purpose here, as the Where call doesn't introduce duplicates (unless of course models has duplicate values, and you want to remove those duplicates).

"Or" equivalent in Linq Where() lambda expression

Try to use PredicateBuilder as the link goes:

public static class PredicateBuilder
{
    public static Expression<Func<T, bool>> True<T> ()  { return f => true;  }
    public static Expression<Func<T, bool>> False<T> () { return f => false; }

    public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
                                                      Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
        return Expression.Lambda<Func<T, bool>>
           (Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
    }

    public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
                                                  Expression<Func<T, bool>> expr2)
    {
        var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
        return Expression.Lambda<Func<T, bool>>
           (Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
    }
}

In your case:

List<string> models = new List<string>
{
    "abcd1234",
    "xycd9999",
    "zzz999z",
    "ros7777"
};
List<string> filterer = new List<string>
{
    "cd",
    "9999"
};
var predicate = PredicateBuilder.False<string>();

foreach (string filter in filterer)
{
    predicate = predicate.Or(f => f.Contains(filter));
}

var filteredList = models.AsQueryable().Where(predicate).ToList();

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