リストに文字列を含む要素が含まれているかどうかを確認し、その要素を取得します


146

この質問への回答を検索しているときに、LINQを利用して同様の質問に出くわしましたが、慣れていないため、それらを完全に理解することはできません(したがって、それらを実装することもできません)。私が基本的にしたいのはこれです:

  1. リストの要素に特定の文字列が含まれているかどうかを確認します。
  2. ある場合は、その要素を取得します。

正直なところ、どうすればいいのかわかりません。私が思いつくことができるのはこれです(もちろん機能していません):

if (myList.Contains(myString))
    string element = myList.ElementAt(myList.IndexOf(myString));

それが機能しない理由を知っています:

  • myList.Contains()trueリストの要素全体が指定した文字列と一致するかどうかをチェックするため、は返されません。
  • myList.IndexOf() それは再びそうであるので、文字列に一致する要素をチェックするので、オカレンスは見つかりません。

それでも、この問題を解決する方法はわかりませんが、同様の質問で提案されているように、LINQを使用する必要があると思います。そうは言っても、ここでそうである場合は、回答者に例でのLINQの使用について説明してほしい(先ほど述べたように、C#のときは気にしていません)。事前にみんな(そしてギャル?)ありがとうございました。

編集:私は解決策を考え出しました; リストをループして、現在の要素に文字列が含まれているかどうかを確認し、現在の要素と等しい文字列を設定します。しかし、これより効率的な方法はありますか?

string myString = "bla";
string element = "";

for (int i = 0; i < myList.Count; i++)
{
    if (myList[i].Contains(myString))
        element = myList[i];
}

私の回答で述べているように、古いファッションループ(あなたがあなたの質問として持っているようなもの)はほとんど常に最速です。しかし、十分に注意すれば、パフォーマンスをテストできます。
マッケイ

stringを含むリストに複数の文字列が含まれている可能性がありmyStringます。現在のループでは、最後の要素を取得します。最初と最後のどちらを検索するか、最初だけを検索するかどうかはあなた次第です。アイテムを見つけた後、ループを解除します。
ハビブ2013

回答:


193

ここでLinqを使用できるはずです。

var matchingvalues = myList
    .Where(stringToCheck => stringToCheck.Contains(myString));

最初に一致したアイテムを返すだけの場合:

var match = myList
    .FirstOrDefault(stringToCheck => stringToCheck.Contains(myString));

if(match != null)
    //Do stuff

1 -または交換WhereFirstOrDefault 2番目のケースでmyList.FirstOrDefault(stringToCheck => stringToCheck.Contains(myString))
ハビブ

すばらしい答えです。しかし、好奇心から抜け出して:matchingコンパイラが決定するのはなぜvarですか()?リストのタイプがであることを知っているので、この場合Stringに使用string matchingしても安全ですか?
Dimitris Iliadis 2013

1
@JimIliadis "var"と "string"は、この場合はまったく同じことを意味します。コンパイラーは、結果が'string' のみになる可能性があることを認識できるほどスマートです。varは実際には単なるコーディングスタイルのものです(匿名型を使用しない場合)
Dave Bish

古いスレッドにコメントしましたが、これに関する例外が1つ見つかりました。firstordefault()を使用する場合は、デフォルト値も返せることを確認してください。したがって、空の文字列、つまりmystring = ""を渡していて、何も表示されないことを期待しているものの、firstordefaultを選択したため、リストの最初の項目が表示されるとしましょう。
汚い開発者

@DirtyDeveloperこれが何を意味するのかわからない-ターゲットリストに空の文字列がない場合、この例では 'null'が返されます。構造体タイプでFirstOrDefault()を使用しようとしている場合は正しいです。たとえば、List <int>-FirstOrDefault()はnullではなく「0」を返します-ただし、質問は文字列に関するものでした
Dave Bish

29

基本的な答えは次のとおりです。ループを反復処理して、指定した文字列が含まれている要素を確認する必要があります。したがって、コードが次のとおりだとします。

foreach(string item in myList)
{
    if(item.Contains(myString))
       return item;
}

同等の簡潔なコードは次のとおりです。

mylist.Where(x => x.Contains(myString)).FirstOrDefault();

ここで、xは上記のコードの「item」のように機能するパラメーターです。


12
string result = myList.FirstOrDefault(x => x == myString)
if(result != null)
{
  //found
}

9
for (int i = 0; i < myList.Length; i++)
{
    if (myList[i].Contains(myString)) // (you use the word "contains". either equals or indexof might be appropriate)
    {
        return i;
    }
}

ほとんどの場合、古いファッションのループが最速です。


私は効率を追求しているので、この方法の方が速い(つまり、より効率的)であることを示唆していますか?
Dimitris Iliadis 2013

2
私はそれをperfでテストしていませんが、これはより速くなると思います。リストを1回パスするだけで、何かを見つけて早期に抜け出すまで(Linqオプションが適切に記述されている場合はそうなる可能性があります)、linqのメソッド呼び出しオーバーヘッドも、linqのラムダオーバーヘッドもありません。これらは大きな懸念事項ではありませんが、パフォーマンスに影響を与える可能性があります。
マッケイ

List.Equals()を使用しないのはなぜですか?
F8ER

@ V.7彼は、リストの1つの項目に部分文字列が含まれているかどうかを知りたいだけだからです。list.equalsは、ジョブの正しいツールではありません["abc"、 "def"、 "ghi"]には、OPが記述する方法で "hi"が含まれています。list.equalsは正しいデータ型を取りさえしません。
マッケイ

6

文字列を含む文字列のリストが必要な場合:

var newList = myList.Where(x => x.Contains(myString)).ToList();

別のオプションは、Linq FirstOrDefaultを使用することです

var element = myList.Where(x => x.Contains(myString)).FirstOrDefault();

このContains方法では大文字と小文字が区別されることに注意してください。


1
大文字と小文字を区別することについての良いリマインダー、StringComparison.InvariantCultureIgnoreCaseを実装
JoshYates1980

2

LinqのFirstOrDefault拡張メソッドを使用できます。

string element = myList.FirstOrDefault(s => s.Contains(myString));

これは、部分文字列を含む最初の要素を返すmyStringnull、そのような要素が見つからない場合に返します。

必要なのがインデックスだけの場合は、List<T>クラスのFindIndexメソッドを使用します。

int index = myList.FindIndex(s => s.Contains(myString));

これは、部分文字列を含む最初の要素のインデックスを返すmyString-1、そのような要素が見つからない場合に返します。


2

ここには多くの良い答えがありますが、以下のように、私はExistsを使用した簡単な答えを使用しています:

foreach (var setting in FullList)
{
    if(cleanList.Exists(x => x.ProcedureName == setting.ProcedureName)) 
       setting.IsActive = true; // do you business logic here 
    else
       setting.IsActive = false;
    updateList.Add(setting);
}

2

あなたはこのようなものを使うことができるはずです、それは私にとって大丈夫です:

var valuesToMatch = yourList.Where(stringCheck => stringCheck.Contains(myString));

または、それが一致しない場所を調べる必要がある場合は、このようなもの。

 var valuesToMatch = yourList.Where(stringCheck => !stringCheck.Contains(myString));

1

あなたは使うことができます

var match=myList.Where(item=>item.Contains("Required String"));
foreach(var i in match)
{
//do something with the matched items
}

LINQは、データのコレクションを「クエリ」する機能を提供します。コレクション(ここでは文字列のコレクション(リスト))に対してデータベースクエリ(select、whereなど)のような構文を使用できます。

「リストからアイテムを取得して、指定された条件を満たす場所で」のようにします

「ラムダ式」を使用している場所の内部

ラムダ式を簡単に言うと(入力パラメーター=>戻り値)のようなものです

そのため、パラメータ「item」の場合、「item.Contains( "required string")」を返します。そのため、アイテムに文字列が含まれ、条件を満たしたためにリストから選択された場合、trueを返します。


1

シンプルに保つには、これを使用します。

foreach(string item in myList)//Iterate through each item.
{
 if(item.Contains("Search Term")//True if the item contains search pattern.
 {
   return item;//Return the matched item.
 }
}

または、forループでこれを行うには、これを使用します。

    for (int iterator = 0; iterator < myList.Count; iterator++)
    {
        if (myList[iterator].Contains("String Pattern"))
        {
            return myList[iterator];
        }
    }

指摘しておきますが、コード行の1つに終了ブラケットがありませんでした。if(item.Contains( "Search Term"))
Alex

0

私は他の答えでブールオプションを見たことがないので、以下のコードが誰かを助けることを願っています。

使うだけ Any()

string myString = "test";
bool exists = myList
             .Where(w => w.COLUMN_TO_CHECK.Contains(myString)).Any();

0

Any、Where、First、FirstOrDefaultを組み合わせることができます。または、必要に応じて、これらのメソッドのいずれかに述語を配置するだけです。

一致が見つからないときに例外がスローされるようにする場合を除き、Firstの使用はおそらく避けるべきです。FirstOrDefaultは、一致が見つからない場合にタイプのデフォルトを返すことがわかっている限り、通常はより良いオプションです(文字列のデフォルトはnull、intは0、boolはfalseなど)。

using System.Collections.Generic;
using System.Linq;


bool exists;
string firstMatch;
IEnumerable<string> matchingList;

var myList = new List<string>() { "foo", "bar", "foobar" };

exists = myList.Any(x => x.Contains("o"));
// exists => true

firstMatch = myList.FirstOrDefault(x => x.Contains("o"));
firstMatch = myList.First(x => x.Contains("o"));
// firstMatch => "foo"

firstMatch = myList.First(x => x.Contains("dark side"));
// throws exception because no element contains "dark side"

firstMatch = myList.FirstOrDefault(x => x.Contains("dark side"));
// firstMatch => null

matchingList = myList.Where(x => x.Contains("o")); 
// matchingList => { "foo", "foobar" }

このコードをhttps://rextester.com/TXDL57489でテストします

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.