查找列表中包含任何一个字符串的任何实体

时间:2013-03-12 19:54:52

标签: c# linq generics

出于某种原因,我无法理解这一点。

假设我们有一个班级Foo

public class Foo
{
    public string Name {get;set;}
}

我们有一个通用的列表。我想搜索通用列表,并从字符串列表中挑选出包含Name的那些。

类似

var source = GetListOfFoos();//assume a collection of Foo objects
var keywords = GetListOfKeyWords();//assume list/array of strings
var temp = new List<Foo>();
foreach(var keyword in keywords)
{
    temp.AddRange(source.Where(x => x.Name.Contains(keyword));
}

这个问题在这里是a)循环(对我来说感觉不太理想)和b)每个对象可能出现不止一次(如果名称是'Rob StackOverflow'并且有一个关键字'Rob'和关键字'计算器')。

我想我可以拨打Distinct()但是再一次,它感觉不太理想。

我认为我正在接近这个错误 - 我做错了什么?


2 个答案:

答案 0 :(得分:2)

  

我想搜索通用列表并挑选出那些   包含字符串列表中任何一个的名称。

听起来很简单:

var query = source.Where(e => keywords.Any(k => e.Name.Contains(k)));

添加ToList()以获得List<Foo>的结果:

var temp = query.ToList();

答案 1 :(得分:1)

将关键字放入HashSet中以便快速查找,这样就不会进行N 2 循环。

HashSet<string> keywords = new HashSet<string>(GetListOfKeyWords(), StringComparer.InvariantCultureIgnoreCase);

var query = source.Where(x => keywords.Contains(x.Name));
编辑:实际上,我重新阅读了这个问题,并且错了。这只会匹配整个关键字,而不会查看Name是否包含关键字。致力于更好的解决方案。

我喜欢MarcinJuraszek的回答,但我也假设您希望关键字不区分大小写,所以我会尝试这样的事情:

var query = source.Where(f => keywords.Any(k => f.Name.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0));