c# 체크 - 대소 문자를 구분하지 않는 목록 검색




대소문자 (6)

위의 아담 샐스 (Aam Sills)의 대답을 기반으로 - Contains ...에 대한 멋진 확장 방법이 있습니다.

///----------------------------------------------------------------------
/// <summary>
/// Determines whether the specified list contains the matching string value
/// </summary>
/// <param name="list">The list.</param>
/// <param name="value">The value to match.</param>
/// <param name="ignoreCase">if set to <c>true</c> the case is ignored.</param>
/// <returns>
///   <c>true</c> if the specified list contais the matching string; otherwise, <c>false</c>.
/// </returns>
///----------------------------------------------------------------------
public static bool Contains(this List<string> list, string value, bool ignoreCase = false)
{
    return ignoreCase ?
        list.Any(s => s.Equals(value, StringComparison.OrdinalIgnoreCase)) :
        list.Contains(value);
}

나는 문자열 묶음을 포함하는리스트 testList 를 가지고있다. 목록에 이미 존재하지 않는 경우에만 새 문자열을 testList 에 추가하고 싶습니다. 따라서 목록의 대 / 소문자를 구분하지 않고 검색하는 것이 효율적이어야합니다. 나는 그것이 케이스를 고려하지 않기 때문에 Contains 사용할 수 없다. 성능상의 이유로 ToUpper/ToLower 를 사용하고 싶지 않습니다. 나는이 방법을 발견했다.

    if(testList.FindAll(x => x.IndexOf(keyword, 
                       StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)
       Console.WriteLine("Found in list");

이것은 작동하지만 부분 단어와도 일치합니다. 목록에 "염소"가 들어 있으면 "귀리"가 이미 목록에 있으므로 "귀리"를 추가 할 수 없습니다. 단어가 정확히 일치해야하는 대소 문자를 구분하지 않고 효율적으로 목록을 검색 할 수있는 방법이 있습니까? 감사


String.IndexOf 대신 String.Equals 를 사용 String.Equals 부분 일치가 없는지 확인하십시오. 또한 FindAll을 사용하지 마십시오. FindAll은 모든 요소를 ​​통과하므로 FindIndex 사용합니다 (첫 번째 요소에서 멈 춥니 다).

if(testList.FindIndex(x => x.Equals(keyword,  
    StringComparison.OrdinalIgnoreCase) ) != -1) 
    Console.WriteLine("Found in list"); 

또는 일부 LINQ 메서드를 사용합니다 (이 메서드는 적중 한 첫 번째 메서드에서 중지됩니다)

if( testList.Any( s => s.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) )
    Console.WriteLine("found in list");

IndexOf의 결과가 더 크거나 같으면 문자열의 어느 위치에서든 일치가 시작되는지 여부를 확인합니다. 0 과 같은지 확인해보십시오.

if (testList.FindAll(x => x.IndexOf(keyword, 
                   StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)
   Console.WriteLine("Found in list");

이제 "염소"와 "귀리"는 일치하지 않지만 "염소"와 "고아"는 일치합니다. 이것을 피하기 위해 두 문자열의 길이를 비교할 수 있습니다.

이러한 모든 복잡성을 피하기 위해 목록 대신 사전을 사용할 수 있습니다. 키는 소문자 문자열이고 값은 실제 문자열입니다. 이렇게하면 각 비교에 ToLower 를 사용할 필요가 없기 때문에 성능이 손상되지 않지만 Contains 계속 사용할 수 Contains .


Lance Larsen의 답을 바탕으로 - 여기에 권장되는 문자열을 사용한 확장 방법이 있습니다. 문자열 대신에 사용합니다 .Equals

StringComparison 매개 변수를 사용하는 String.Compare 오버로드를 사용하는 것이 좋습니다. 이러한 오버로드로 인해 의도 한 정확한 비교 동작을 정의 할 수있을뿐 아니라 다른 개발자가 코드를 더 쉽게 읽을 수 있습니다. [ 조쉬 프리 @ BCL 팀 블로그 ]

public static bool Contains(this List<string> source, string toCheck, StringComparison comp)
{
    return
       source != null &&
       !string.IsNullOrEmpty(toCheck) &&
       source.Any(x => string.Compare(x, toCheck, comp) == 0);
}

비슷한 문제가 있었지만 항목의 색인이 필요했지만 대소 문자를 구분하지 않아야했습니다. 몇 분 동안 웹을 둘러 보았고 아무 것도 발견하지 못했기 때문에 작은 방법으로 작업을 완료했습니다. 않았다 :

private static int getCaseInvariantIndex(List<string> ItemsList, string searchItem)
{
    List<string> lowercaselist = new List<string>();

    foreach (string item in ItemsList)
    {
        lowercaselist.Add(item.ToLower());
    }

    return lowercaselist.IndexOf(searchItem.ToLower());
}

이 코드를 같은 파일에 추가하고 다음과 같이 호출하십시오.

int index = getCaseInvariantIndexFromList(ListOfItems, itemToFind);

희망이 도움이 행운을 빕니다!


thing[:] 사용 thing[:]

>>> a = [1,2]
>>> b = a[:]
>>> a += [3]
>>> a
[1, 2, 3]
>>> b
[1, 2]
>>> 




c# list search case-insensitive