简体   繁体   English

C# 如何将数组中的所有项目与搜索词列表匹配

[英]C# How to match all items in an array to list of search terms

I have a Recipe class:我有一个食谱 class:

public class Recipe
{
    public string Id { get; set; }
    public string RecipeTitle { get; set; }
    public string ChefName { get; set; }
    public List<string> HashTags { get; set; }
    public string Ingredients { get; set; }
}

The user can input a list of search terms into a search box and I want to return the recipes that match ALL of the search terms.用户可以在搜索框中输入搜索词列表,我想返回与所有搜索词匹配的食谱。 Here is my code so far:到目前为止,这是我的代码:

public Recipe[] SearchRecipes(string[] searchTerms, Recipe[] recipes)
{
    var matches = new List<Recipe>();

    foreach (var recipe in recipes)
    {

        if (searchTerms.Contains(recipe.ChefName, StringComparer.OrdinalIgnoreCase))
        {
            matches.Add(recipe);
        }

        foreach (var tag in recipe.Hashtags)
        {
            if (searchTerms.Contains(tag, StringComparer.OrdinalIgnoreCase))
            {
                matches.Add(recipe);
            }
        }

        foreach (var title in recipe.RecipeTitle)
        {
            if (searchTerms.Contains(title, StringComparer.OrdinalIgnoreCase))
            {
                matches.Add(recipe);
            }
        }
    }

    return matches.Distinct().ToArray();
}

However, this returns items that only match one or two of the criteria.但是,这将返回仅匹配一个或两个条件的项目。 Eg If the user searches "Chef Jane" and "Difficult" it will return also things from "Chef Callum" because the 'difficult' hashtag is present.例如,如果用户搜索“Chef Jane”和“Difficult”,它也会返回来自“Chef Callum”的内容,因为存在“困难”标签。

How can I make sure that the only ones returned are the complete matches?如何确保返回的唯一匹配项是完整匹配项?

I'm not sure what's the logic to traverse through the ingredients in that string, maybe you should make those a list as well.我不确定遍历该字符串中的成分的逻辑是什么,也许您也应该将它们列成一个列表。 Anyway, you could create an array of recipe search terms for each recipe and return all the recipes where all the user input search terms are covered with those recipe search terms.无论如何,您可以为每个食谱创建一个食谱搜索词数组,并返回所有用户输入搜索词都被这些食谱搜索词覆盖的所有食谱。

public Recipe[] SearchRecipes(string[] searchTerms, Recipe[] recipes)
{
    var matches = new List<Recipe>();

    foreach (var recipe in recipes)
    {
        // Just flattening all the hash tags together with other recipe search terms
        var recipeTerms = recipe.HashTags
            .Concat(new string[]
            {
                recipe.RecipeTitle,
                recipe.ChefName,
                recipe.Ingredients
            });

        // Will include only the recipes where all search terms are matched in recipe terms
        if (searchTerms.All(searchTerm =>
                recipeTerms.Contains(searchTerm, StringComparer.OrdinalIgnoreCase))
        {
            matches.Add(recipe);
        }
    }

    return matches.ToArray();
}

You could do the All logic manually as well, but it's simpler this way.您也可以手动执行All逻辑,但这种方式更简单。 It comes from the System.Linq namespace and you can take a look at its documentation here .它来自System.Linq命名空间,您可以在此处查看其文档。

Complete LINQ solution would look something like this:完整的 LINQ 解决方案如下所示:

public Recipe[] SearchRecipes(string[] searchTerms, Recipe[] recipes)
    => recipes.Where(recipe =>
        {
            var recipeTerms = recipe.HashTags
                .Concat(new string[]
                {
                    recipe.RecipeTitle,
                    recipe.ChefName,
                    recipe.Ingredients
                });

            return searchTerms.All(searchTerm =>
                recipeTerms.Contains(searchTerm, StringComparer.OrdinalIgnoreCase));
        })
        .ToArray();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM