【问题标题】:Filtering a collection of items from contents of another collection从另一个集合的内容中过滤一个项目集合
【发布时间】:2010-10-17 06:03:19
【问题描述】:

这曾经对我有用,然后失败了。我只想返回那些包含所有过滤器的项目,而不是像现在这样至少返回一个过滤器。这里有什么问题?

private IQueryable<IndexItem> FilteredIndex (IQueryable<IndexItem> index, IEnumerable<string> filters)

    {

        var filteredIndex= from f in filters.AsQueryable() 
               where f.Length>0
               from i in index 
               where i.FilterNames.Contains(f)
               select i;
        return filteredIndex;
   }

【问题讨论】:

  • 您使用的是哪个 LINQ 提供程序?我假设它不是 LINQ to Objects,基于 IQueryable 的使用。
  • 我可以为 LINQ to Objects 提供一个非常优雅的解决方案,但我不确定它是否适合您。让我听听。

标签: c# linq sorting collections


【解决方案1】:

怎么样:

foreach(string s in filters) {
    if(s.Length == 0) continue;
    string tmp = s; // because of "capture" problem
    index = index.Where(i => i.FilterNames.Contains(tmp));
}
return index;

这会应用一系列 Where 子句,涵盖所有过滤器 - 基本上是 AND

【讨论】:

  • @zsharp Where() 内部的 lambda 是一个闭包。必须保留该迭代的变量 s ,否则在执行 lambda 时它会有所不同。见闭包。​​
  • 因为我们在 lambda 中使用“s”,它实际上被(由编译器)视为编译器生成的类上的一个字段(出于复杂的原因)。问题是“foreach”的性质意味着否则你只会得到其中一个,你会有 n 次 Where([last filter])。
【解决方案2】:

把它转过来。您想要的是索引中的那些项目,其中 FilterNames 中的每个项目在过滤器中都有相应的条目。我不确定它的性能如何,但是应该进行计数比较。比如:

private IQueryable<IndexItem> FilteredIndex(IQueryable<IndexItem> index, IEnumerable<string> filter)
{
    var filteredIndex = from i in index
                        where (from s in i.FilterNames
                               where filter.Contains(s)
                               select s).Count() == i.FilterNames.Count
                        select i;
    return filteredIndex;
}

【讨论】:

    【解决方案3】:

    直截了当。对于索引中的给定项目,检查给定项目包含该过滤器的所有过滤器是否为真。有了这个,只需从索引中选择给定条件为真的所有项目。

    index.Where(item => 
       filters.All(filter => item.FilterNames.Contains(filter)))
    

    我不确定是否需要检查长度是否大于零,但很容易集成。

    index.Where(item => 
       filters.All(filter =>
          (filter.Length > 0 ) || (item.FilterNames.Contains(filter))))
    

    它适用于 LINQ to Objects,我猜它可以满足您的要求,但我不确定它是否适用于 LINQ to SQL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 2014-11-27
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      相关资源
      最近更新 更多