简体   繁体   English

如何获取在string.Contains方法中传递的值?

[英]How to retrieve the value passed in string.Contains method?

Is it possible to retrieve the value passed in the string.Contains method? 是否可以检索在string.Contains方法中传递的值?

The usage scenario would be something like this: 使用场景如下所示:

foreach (string x in myList)
{
    if (x.Contains("Salt") || x.Contains("Sugar") || x.Contains("Pepper"))
    {
        MessageBox.Show("The ingredient found in this line of myList is: " + //the ingredient found)
    }
}

The objective is to AVOID having to repeat code. 目的是避免必须重复代码。 Right now I have to do the following to achieve the desired result: 现在,我必须执行以下操作才能获得所需的结果:

foreach (string x in myList)
{
    if (x.Contains("Salt"))
    {
        MessageBox.Show("The ingredient found in this line of myList is: Salt");
    }

    if (x.Contains("Sugar"))
    {
        MessageBox.Show("The ingredient found in this line of myList is: Sugar");
    }

    if (x.Contains("Pepper"))
    {
        MessageBox.Show("The ingredient found in this line of myList is: Pepper");
    }
}

If it's not possible is there any alternative? 如果不可能,还有其他选择吗?

Thanks in advance! 提前致谢!

You could use the FirstOrDefault LINQ extension method and write something like this: 您可以使用FirstOrDefault LINQ扩展方法并编写如下内容:

string[] ingredients = { "Salt", "Sugar", "Pepper" };
foreach (string x in myList)
{
    string ingredient = ingredients.FirstOrDefault(x.Contains); // i.e., i => x.Contains(i)
    if (ingredient != null)
    {
        MessageBox.Show("The ingredient found in this line of myList is: " + ingredient);
    }
}

If that's a little too cryptic for you, then create an extension method with a descriptive name: 如果这对于您来说太神秘了,那么请创建一个具有描述性名称的扩展方法:

// Put this in a static class somewhere.
public static string FindAny(this string s, params string[] values)
{
    return values.FirstOrDefault(s.Contains);
}

And call it like this: 并这样称呼它:

string ingredient = x.FindAny(ingredients);
// Or, at the expense of extra memory allocations, you could inline the array:
//   string ingredient = x.FindAny("Salt", "Sugar", "Pepper");
if (ingredient != null)
{
    MessageBox.Show("The ingredient found in this line of myList is: " + ingredient);
}

Note: To output multiple ingredients found in the same line, use Where instead of FirstOrDefault: 注意:要输出在同一行中找到的多种成分,请使用Where而不是FirstOrDefault:

string[] ingredients = { "Salt", "Sugar", "Pepper" };
foreach (string x in myList)
{
    List<string> ingredientsFound = ingredients.Where(x.Contains).ToList();
    if (ingredientsFound.Count > 0)
    {
        MessageBox.Show("The ingredient(s) found in this line of myList are: " +
            string.Join(", ", ingredientsFound));
    }
}

This is a simple way of doing this. 这是一种简单的方法。 Also, it prints all of the ingredients found to match a line. 此外,它还会打印找到与行匹配的所有成分。

I like Michael's solution, but knowing you can just do a simple i , j iteration on two arrays is essential. 我喜欢Michael的解决方案,但是知道您可以对两个数组进行简单的ij迭代是必不可少的。

string[] INGREDIENTS = {"Salt", "Sugar"};
foreach (string line in myList)
{
    foreach (string ingredient in INGREDIENTS)
    {   
        if (line.Contains(ingredient))
        {
            MessageBox.Show($"The ingredient found in this line of myList is: {ingredient}");
        }
    }
}

For a broader amount of possible ingredients, and reasonably small strings (but arbitrarily large number of them), using regex can show much better performance, as it doesn't have to iterate the string every time for all ingredients. 对于更广泛的可能成分,以及相对较小的字符串(但任意数量的字符串),使用regex可以显示出更好的性能,因为它不必每次都对所有成分重复字符串。

static readonly Regex ingredientRegex = new Regex("(Salt|Sugar|Pepper)", RegexOptions.Compiled | RegexOptions.CultureInvariant);
static void FindIngredient(string[] myList)
{
    foreach(string x in myList)
    {
        var match = ingredientRegex.Match(x);
        if(match.Success)
        {
            Console.WriteLine("The ingredient found in this line of myList is: " + match.Groups[1].Value);
        }
    }
}

Just remember to construct the Regex object beforehand. 只要记住要事先构造Regex对象即可。

The general solution to this sort of thing is to encapsulate it in your own function that you call. 这类事情的一般解决方案是将其封装在您自己的调用函数中。 Michael Liu's answer might be preferable in the scenario where there are ways to do it with library functions. 在有多种方法可以使用库函数的情况下,Michael Liu的答案可能更可取。 However if there weren't any you would do something like this: 但是,如果没有,您将执行以下操作:

bool ContainsAny(string haystack, IEnumerable<string> needles, out which)
{
    foreach(var s in needles)
    {
        if (haystack.Contains(s))
        {
            which = s;
            return true;
        }
    }
    which = null;
    return false;
}

And then just call that. 然后打电话给。

foreach (string x in myList)
{
     if (x.Contains("Salt") || x.Contains("Sugar") || x.Contains("Pepper"))
     {
         string s = "The ingredient found in this line of myList is: {0}", x;
         MessageBox.Show(s);
     }
}

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

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