使用LINQ获取一个包含另一个列表中某个项目部分的项目列表

3

拥有一个模型列表:

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

拥有一个过滤器列表:

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

我正在尝试使用LINQ获取所有模型,这些模型名称中包含筛选项的一部分。

例如:

  1. "abcd1234"和"xycd9999"都包含"cd"
  2. "xycd9999"包含"9999"

因此,LINQ操作将返回两个项目的列表:"abcd1234"和"xycd9999"。

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

什么是正确的语法?
2个回答

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

在这里,Distinct 没有任何作用,因为 Where 调用不会引入重复项(除非当然 models 具有重复值,并且您想要删除那些重复项)。

0

在Linq Where() lambda表达式中的“或”等效语

尝试使用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();

我可以想到使用PredicateBuilder的两个原因--1)查询正在针对不支持从ContainsAny进行映射的提供程序运行;或2)每个字符串可能遵循自己的逻辑分支(例如,不要应用任何带有空字符串的子句;为数字字符串应用不同的谓词)。但在这种情况下,查询是在内存集合上进行的,并且过滤子句始终相同,因此我无法看到在这里使用PredicateBuilder的好处。 - Zev Spitz
针对所提到的情况,不需要使用PredicateBuilder,只是在其他情况下的另一种选择。 - Levanan Gan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接