C #에서 문자열 키 유형의 대소 문자 구분 사전


155

내가 있다면 대소 문자를 구분하지 않는 Dictionary<String,...>방법을 만들 수 ContainsKey있습니까?

이것은 관련이있는 것처럼 보였지만 제대로 이해하지 못했습니다 : c # Dictionary : 선언을 통해 키를 대소 문자를 구분하지 않습니다


5
사용에 어떤 문제가 StringComparer.InvariantCultureIgnoreCase있습니까? 그것은 무엇을 말하는가 ...
leppie

5
나는 그것을 들어 본 적이 없으므로 질문입니다!
Mr. Boy


그 질문은 관련이 있지만이 질문과는 전혀 다릅니다. 그것은 기존의 사전을 다루는 방법을 알게됩니다. 새 코드로 시작하므로 여기에 대한 답변이 더 적합합니다.
goodeye 2019

답변:


321

이것은 관련이있는 것처럼 보였지만 제대로 이해하지 못했습니다 : c # Dictionary : 선언을 통해 키를 대소 문자를 구분하지 않습니다

실제로 관련이 있습니다. 해결책은 사전 인스턴스에 표준 문자열 비교 방법 (대소 문자 구분)을 사용하지 말고 대소 문자를 구분하지 않는 것입니다. 이것은 적절한 생성자를 사용하여 수행됩니다 .

var dict = new Dictionary<string, YourClass>(
        StringComparer.InvariantCultureIgnoreCase);

생성자는 IEqualityComparer키를 비교하는 방법을 사전에 알려주 는를 기대 합니다.

StringComparer.InvariantCultureIgnoreCaseIEqualityComparer대소 문자를 구분하지 않고 문자열을 비교 하는 인스턴스를 제공합니다 .


1
완벽하게, 나는 비교기를 ctor로 전달하는 STL과 같은 방법을 놓쳤다.
Mr. Boy

7
내가 여기서 항상 코딩 질문에 대한 답을 찾는 방법을 놀라게하는 것은 결코 끝나지 않습니다! 어쩌면 Konrad! :-)
Jamie

10
문화 기반보다 더 빠른 StringComparison.OrdinalIgnoreCase
비교기

사전을 만들지 않고 개체의 일부로 얻는 기존 사전에서 대 / 소문자를 구분하지 않는 키 일치를 위해 ContainsKey ()를 사용하려고하면 어떻게합니까?
Shridhar R Kulkarni

1
@ShridharRKulkarni 당신은 근본적으로 (효율적으로) 할 수 없습니다. 비교 논리는 내부 사전 데이터 구조의 핵심 부분입니다. 이를 허용하기 위해 컨테이너는 데이터에 대해 여러 개의 인덱스를 유지해야하며 사전은이를 수행하지 않습니다.
Konrad Rudolph

21
var myDic = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
myDic.Add("HeLlo", "hi");

if (myDic.ContainsKey("hello"))
    Console.WriteLine(myDic["hello"]);

1
코드 스 니펫이 모든 것을 말합니다. 매우 도움이됩니다. 이 게시물이 왜 3 분 늦게 수락 된 답변에 비해 투표율이 낮은 지 확실하지 않습니다.
RBT

14

타사 또는 외부 dll에서 가져온 사전을 다루는 경우는 거의 없습니다. linq 사용

YourDictionary.Any(i => i.KeyName.ToLower().Contains("yourstring")))


3
이것은 잘 작동합니다. 변경할 경우주의의 단어는, 비록 AnySingleOrDefault받지 않습니다 당신 null이 존재하지 않는 경우 다시, 대신 당신은에 키와 값 세트 모두와 keyvaluepair을 얻을 것이다 null!
NibblyPig

1
Contains당시에 작업했던 것에 대한 매우 구체적인 유스 케이스처럼 보입니다. 더 일반적인 도움이되는 답변 Equals으로 더 좋습니다. 같은 메모에서으로 문자열을 복제하는 대신 ToLower()을 사용하는 것이 더 좋습니다 StringComparison.xxxCase.
Suamere

1
이것은 매우 유용하고 ToLower를 제거하는 것이 확실히 개선되었습니다. 내 유스 케이스는 다음과 같습니다. return AppliedBuffs.Any (b => b.Key.Equals (Name, StringComparison.OrdinalIgnoreCase)); 대소 문자를 구분하지 않는 대소 문자를 구분하는 사전을 포함합니다.
David Burford

나는 이것을 내려 놓았다. 주의 할 점은, 사전의 소유자라면 이것이 가장 확실한 방법은 아닙니다. 사전의 인스턴스화 방법을 모르는 경우에만이 방법을 사용하십시오. 그럼에도 불구하고 (일부 일치가 아닌) 문자열의 정확한 일치 dict.Keys.Contains("bla", appropriate comparer)를 위해 사용 편의성을 위해 LINQ 과부하를 사용하십시오.
nawfal

1

ASP.NET Core 컨트롤러에서 caseINsensitive 사전이 필요한 동일한 종류의 문제가 발생했습니다.

트릭을 수행하는 확장 방법을 작성했습니다. 아마도 이것은 다른 사람들에게도 도움이 될 수 있습니다 ...

public static IDictionary<string, TValue> ConvertToCaseInSensitive<TValue>(this IDictionary<string, TValue> dictionary)
{
    var resultDictionary = new Dictionary<string, TValue>(StringComparer.InvariantCultureIgnoreCase);
    foreach (var (key, value) in dictionary)
    {
        resultDictionary.Add(key, value);
    }

    dictionary = resultDictionary;
    return dictionary;
}

확장 방법을 사용하려면

myDictionary.ConvertToCaseInSensitive();

그런 다음 사전을 사용하여 값을 가져옵니다.

myDictionary.ContainsKey("TheKeyWhichIsNotCaseSensitiveAnymore!");

0

인스턴스 생성을 제어 할 수없는 경우 객체가 json 등으로부터 desterilized되었다고 가정하면 사전 클래스에서 상속되는 래퍼 클래스를 만들 수 있습니다.

public class CaseInSensitiveDictionary<TValue> : Dictionary<string, TValue>
{
    public CaseInSensitiveDictionary() : base(StringComparer.OrdinalIgnoreCase){}
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.