관리되는 dll을 사용하는 응용 프로그램이 있습니다. 해당 dll 중 하나가 일반 사전을 반환합니다.
Dictionary<string, int> MyDictionary;
사전에는 대소 문자가 포함 된 키가 포함되어 있습니다.
다른 측면에서 잠재적 인 키 (문자열) 목록을 얻었지만이 경우를 보장 할 수는 없습니다. 키를 사용하여 사전의 값을 얻으려고합니다. 그러나 사례가 일치하지 않기 때문에 물론 다음이 실패합니다.
bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );
TryGetValue가 MSDN doc 에서 언급 한 것과 같이 무시 사례 플래그를 가지기를 희망 했지만 일반 사전에는 유효하지 않은 것 같습니다.
주요 사례를 무시하고 해당 사전의 가치를 얻는 방법이 있습니까? 적절한 StringComparer.OrdinalIgnoreCase 매개 변수 를 사용하여 사전의 새 사본을 작성하는 것보다 더 나은 해결 방법이 있습니까?
답변
StringComparer
값을 얻으려고 할 때 지점 을 지정할 방법이 없습니다 . 당신이 그것에 대해 생각 "foo".GetHashCode()
하고 "FOO".GetHashCode()
완전히 다르므로 대소 문자를 구분하지 않는 해시 맵에서 대소 문자를 구분하지 않는 get을 구현할 수있는 합리적인 방법이 없습니다.
그러나 먼저 다음을 사용하여 대소 문자를 구분하지 않는 사전을 작성할 수 있습니다.
var comparer = StringComparer.OrdinalIgnoreCase;
var caseInsensitiveDictionary = new Dictionary<string, int>(comparer);
또는 대소 문자를 구분하지 않는 기존 사전의 내용을 사용하여 대소 문자를 구분하지 않는 새 사전을 작성하십시오 (대소 문자 충돌이없는 경우).
var oldDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var newDictionary = new Dictionary<string, int>(oldDictionary, comparer);
이 새 사전은 그 사용 GetHashCode()
에 구현 StringComparer.OrdinalIgnoreCase
있도록 comparer.GetHashCode("foo")
하고 comparer.GetHashcode("FOO")
당신에게 같은 값을 제공합니다.
또는 사전에 요소가 몇 개만 있거나 한두 번만 조회해야하는 경우 원래 사전을 하나로 간주하고 IEnumerable<KeyValuePair<TKey, TValue>>
반복 할 수 있습니다.
var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var value = myDictionary.FirstOrDefault(x => String.Equals(x.Key, myKey, comparer)).Value;
또는 원하는 경우 LINQ없이 :-
var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
int? value;
foreach (var element in myDictionary)
{
if (String.Equals(element.Key, myKey, comparer))
{
value = element.Value;
break;
}
}
이렇게하면 새 데이터 구조를 만드는 데 드는 비용이 절약되지만 대신 조회 비용은 O (1) 대신 O (n)입니다.
답변
정규 사전 생성자를 사용하지 않는 LINQers에게는 다음이 있습니다.
myCollection.ToDictionary(x => x.PartNumber, x => x.PartDescription, StringComparer.OrdinalIgnoreCase)
답변
매우 우아하지는 않지만 사전 작성을 변경할 수없는 경우 더러운 해킹 만 있으면됩니다.
var item = MyDictionary.Where(x => x.Key.ToLower() == MyIndex.ToLower()).FirstOrDefault();
if (item != null)
{
TheValue = item.Value;
}