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

Check if string contains a list of strings in any order

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

因此,如果用户搜索 "green shirt",returned 列表将包括 "green t-shirt large"、"t-shirt green medium" 等。我的(错误)代码:

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]) ...

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

我认为您正在寻找 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。所以我加了它。

在 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 命令,因为 table 中有约 30,000 种产品,这会减慢速度。

谢谢大家的帮助。

您可以使用 LINQ 方法 All

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

我使用了 aloisdg dotnetfiddle 并更新了我的答案。