2017-09-24 9 views
1

string.Containsメソッドで渡された値を取得することは可能ですか?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"); 
    } 
} 

代替手段はありませんか?

ありがとうございます!

+0

ディクショナリオブジェクトを見てください。 – user12345

+1

xにそれらのすべてが含まれているとどうなりますか? – IllidanS4

+0

@ IllidanS4、この場合は問題ではないと想像してください。私は、各行について1つのオカレンスしか存在しないことを事前に知っているから(もしあれば)。 – AlexC

答えて

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

注:同じ行で見つかった出力の複数の成分に、どこ代わりに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)); 
    } 
} 
+0

マイケルありがとう、これが解決!同じ行にある複数の一致を出力する方法をデモンストレーションすることは素晴らしいことです。この問題に対する他の解決策を提供してくれた他の人にも感謝します。 – AlexC

2

これは、これを行うための簡単な方法です。また、見つかったすべての成分をラインにマッチさせて印刷します。

私はマイケルの解が好きですが、あなたは単純にijという2つの配列の繰り返しを行うことができます。

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

そして、それを呼び出してください。

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

ただ、事前に正規表現オブジェクトを構築することを忘れないでください。

+0

この場合、 'match.Value'もうまくいくので、正規表現のカッコを削除することができます。 –

+0

@MichaelLiuええ、私はそれを考えましたが、パフォーマンスに大きな影響を与えませんでした。 – IllidanS4

関連する問題