检查字符串是否包含任何顺序的字符串列表

时间:2015-01-26 01:09:43

标签: c# string linq contains

基本上,我有一个产品列表和一个搜索选项。当搜索多个单词时,我想返回任何包含按任何顺序搜索的所有单词的产品。

因此,如果用户搜索"绿色衬衫",则返回的列表将包括"绿色T恤大"," T恤绿色媒体"等我的(坏)代码:

public List<Products> FindProductsByName(string query, int limit)
{
    string[] words = query.ToLower().Split(' ');
    List<Products> products = new List<Products>();
    foreach (var word in words)
    {
        products.AddRange(All.Where(x => x.ProductName.ToLower().Contains(word)).Take(limit).ToList());
        //this will return all products which contains ANY word in the searched word list
    }
    return products;
}

所以基本上,我想要

All.Where(x => x.Productname.ToLower().Contains(words[0]) && x.Productname.ToLower().Contains(words[1]) ...

但我不知道搜索查询中会有多少单词。我觉得这应该很容易,但我的大脑并非如此。今天工作。我错过了什么?

3 个答案:

答案 0 :(得分:4)

我认为您正在寻找Linq方法Intersect()

dotnetfiddle上的工作示例。

代码:

public static void Main()
{
    var list = FindProductsByName("green shirt", 2);
    foreach (var products in list)
        Console.WriteLine(products.ProductName);
}

public static IEnumerable<Products> FindProductsByName(string query, int limit)
{
    string[] words = query.ToLower().Split(' ');
    List<Products> products = new List<Products>
    {
        new Products { ProductName = "green t-shirt large" },
        new Products { ProductName = "t-shirt green medium" },
        new Products { ProductName = "t-shirt red" }
    };
    return
        (from p in products
        let productsComponent = p.ProductName.Split(' ') // you should make a list of keyword in Products instead
        where productsComponent.Intersect(words).Any()
        select p).Take(limit);
}

public class Products
{
    public string ProductName { get; set; }
}

输出

green t-shirt large
t-shirt green medium

编辑:我忘了添加limit。所以我加了它。

答案 1 :(得分:2)

在aloisdg发布他出色的解决方案之前,我能够提出一个有效的解决方案。这是我的工作代码:

string[] words = query.ToLower().Split(' ');
var products = from p in All select p;
foreach (var word in words)
{
    products = products.Where(x => x.ProductName.ToLower().Contains(word));
}
return products.Take(limit).ToList();

我想避免将产品名称分解为字符串数组并使用intersect命令,因为表中有大约30,000个产品,这会减慢速度。

感谢大家的帮助。

答案 2 :(得分:0)

您可以使用LINQ方法All

products.Where(p=> words.All(w=> p.ProductName.Contains(w));

我拿了aloisdg dotnetfiddle并更新了我的答案。