如何检索string.Contains方法中传递的值?

时间:2017-09-24 14:32:45

标签: c# .net

是否可以检索string.Contains方法中传递的值?

使用场景将是这样的:

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)
    }
}

目标是避免重复代码。现在我必须做以下事情才能达到预期的效果:

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");
    }
}

如果不可能有替代方案吗?

提前致谢!

5 个答案:

答案 0 :(得分:6)

您可以使用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);
    }
}

如果这对您来说有点过于神秘,那么请创建一个带有描述性名称的扩展方法:

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

并称之为:

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);
}

注意:要输出在同一行中找到的多个成分,请使用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));
    }
}

答案 1 :(得分:2)

这是一种简单的方法。此外,它打印所有找到的符合一条线的成分。

我喜欢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}");
        }
    }
}

答案 2 :(得分:2)

对于更广泛的可能成分和相当小的字符串(但任意大量的字符串),使用正则表达式可以显示更好的性能,因为它不必每次都为所有成分迭代字符串。

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);
        }
    }
}

请记住事先构建 Regex 对象。

答案 3 :(得分:1)

这类事情的一般解决方案是将其封装在您调用的函数中。 Michael Liu的答案可能更适用于有图书馆功能的方法。但是,如果没有,你会做这样的事情:

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;
}

然后就这样打电话。

答案 4 :(得分:0)

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);
     }
}