使用LINQ获取项目列表,其中项目包含来自另一个列表的项目的一部分

时间:2018-01-14 15:18:16

标签: c# linq

有一个模型列表:

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

有过滤器清单:

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

我正在尝试使用LINQ将所有包含其名称的模型作为过滤器项目。

对于此示例:

  1. &#34; ABCD1234&#34;和&#34; xycd9999&#34;包含&#34; cd&#34;
  2. &#34; xycd9999&#34;包含&#34; 9999&#34;
  3. 因此LINQ操作将返回两个项目的列表:&#34; abcd1234&#34;和&#34; xycd9999&#34;。

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

    正确的语法是什么?

2 个答案:

答案 0 :(得分:7)

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

Distinct此处没有用处,因为Where调用不会引入重复项(除非models具有重复值,并且您想要删除这些重复项)。

答案 1 :(得分:0)

"Or" equivalent in Linq Where() lambda expression

尝试使用PredicateBuilder作为链接:

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

在你的情况下:

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