리스트에 문자열을 포함하는 요소가 포함되어 있는지 확인하고 해당 요소를 가져옵니다.


146

이 질문에 대한 답변을 검색하는 동안 LINQ를 사용하는 비슷한 질문을 겪었지만 익숙하지 않아서 완전히 이해할 수는 없었으므로 구현할 수 없었습니다. 기본적으로 내가 원하는 것은 다음과 같습니다.

  1. 목록의 요소에 특정 문자열이 포함되어 있는지 확인하십시오.
  2. 그렇다면 그 요소를 얻으십시오.

나는 솔직히 내가 그 일을 어떻게 할 것인지 모른다. 내가 생각해 낼 수있는 것은 이것입니다 (물론 작동하지 않습니다).

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

왜 작동하지 않는지 알고 있습니다.

  • myList.Contains()true목록의 전체 요소가 지정한 문자열과 일치하는지 확인하기 때문에를 반환하지 않습니다 .
  • myList.IndexOf() 다시 발생하는 것처럼 문자열과 일치하는 요소를 검사하므로 발생을 찾지 못합니다.

여전히이 문제를 해결하는 방법에 대한 단서가 없지만 비슷한 질문에서 제안 된대로 LINQ를 사용해야한다고 생각합니다. 즉, 여기에 해당되는 경우 응답자가 LINQ를 예제에서 사용하는 방법을 설명하고 싶습니다. 미리 감사드립니다.

편집 : 나는 해결책을 생각해 냈습니다. 목록을 반복하고 현재 요소에 문자열이 포함되어 있는지 확인한 다음 문자열을 현재 요소와 동일하게 설정하십시오. 그러나 이것보다 더 효율적인 방법이 있는지 궁금합니다.

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

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

내 대답에서 언급했듯이 구식 패션 루프 (질문과 마찬가지로)는 거의 항상 가장 빠릅니다. 그러나 충분히 신경 쓰면 성능을 테스트 할 수 있습니다.
McKay

string을 포함하는 목록에 여러 문자열이있을 수 있으며 myString현재 루프에는 마지막 요소가 있습니다. 첫 번째 또는 마지막을 찾으려면, 당신이 첫 번째를 찾으려면 항목을 찾은 후 루프를 끊으십시오.
Habib

답변:


193

Linq를 사용할 수 있어야합니다.

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

첫 번째로 일치하는 항목을 반환하려는 경우 :

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

if(match != null)
    //Do stuff

한 - 또는 교체 WhereFirstOrDefault두 번째 경우myList.FirstOrDefault(stringToCheck => stringToCheck.Contains(myString))
하비브

좋은 대답입니다. 그래도 호기심에서 matching컴파일러가 결정한 이유는 var무엇입니까 ( )? 내 목록이 유형이라는 것을 알고 String있으므로이 경우에 사용하는 것이 안전 string matching합니까?
Dimitris Iliadis

1
@JimIliadis "VAR"과 "문자열"이 경우 정확히 같은 뜻 - 컴파일러는 결과가 수 있음을 알 수있는 스마트 충분하다 '문자열'수는. VAR 정말 (익명 형식을 사용하지 않는) 단지 코딩 스타일 일
데이브 Bish

너무 오래된 스레드에 댓글을 달았지만 이에 대한 예외가 발견되었습니다. firstordefault ()를 사용할 때 기본값도 반환 할 수 있는지 확인하십시오. 그래서 당신이 empy 문자열, 즉 mystring = ""을 전달한다고 가정하고 아무것도 표시하지 않을 것으로 예상하지만 firstordefault를 선택했기 때문에 여전히 목록의 첫 번째 항목을 표시합니다.
더티 개발자

@DirtyDeveloper 무슨 의미인지 잘 모르겠습니다. 대상 목록에 빈 문자열이 없으면 예제는 'null을 반환합니다. 당신이 구조체 유형에 FirstOrDefault ()를 사용하려고 시도하는 경우 당신이 맞아요, 예를 들어 목록 <INT> - FirstOrDefault () '0'을 반환하지 널 것이다 - 그러나, 문제는 문자열에 대해 특별히이었다
데이브 Bish

29

기본적인 대답은 다음과 같습니다. 루프를 반복하고 지정된 문자열이 포함 된 요소를 확인해야합니다. 코드가 다음과 같다고 가정 해 봅시다.

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

동등하지만 간결한 코드는 다음과 같습니다.

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

여기서 x는 위 코드에서 "항목"과 같은 역할을하는 매개 변수입니다.


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

2
나는 그것을 성능 테스트하지 않았지만 이것이 더 빠를 것이라고 생각합니다. Linq 옵션이 잘 작성된 경우와 같이 무언가를 발견하고 조기에 나올 때까지 목록을 한 번만 통과하면 linq의 메소드 호출 오버 헤드 또는 linq의 람다 오버 헤드가 없습니다. 이것이 큰 우려의 원인은 아니지만 성능 저하를 일으킬 수 있습니다.
McKay

왜 List.Equals ()를 사용하지 않습니까?
F8ER

@ V.7 목록의 한 항목에 하위 문자열이 포함되어 있는지 알고 싶어하기 때문입니다. list.equals는 작업에 대한 올바른 도구가 아닙니다 [ "abc", "def", "ghi"]는 OP가 설명하는 방식에 "hi"를 포함합니다. list.equals는 올바른 데이터 유형을 취하지도 않습니다.
McKay

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

하위 문자열을 포함 myString하거나 null해당 요소가없는 경우 fist 요소를 반환합니다 .

인덱스 만 있으면 List<T>클래스의 FindIndex메서드를 사용하십시오 .

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

하위 문자열을 포함 myString하거나 -1그러한 요소를 찾을 수없는 경우 fist 요소의 인덱스를 반환합니다 .


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 ")"을 반환합니다. 따라서 항목에 문자열이 포함되어 있으면 조건을 만족하므로 목록에서 선택됩니다.


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

간단히 말해, 코드 줄 중 하나에서 종료 괄호를 놓쳤습니다. 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를 사용하지 않는 것이 좋습니다. 일치하는 항목이 없으면 문자열의 기본값이 반환됩니다 (문자열의 기본값은 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.