2011-12-14 1 views
5

나는 다음과 같은 데이터 구조를 가지고 :방법이 사전 <문자열 목록 <string>> 사이의 값 비교를 위해 개체를

Dictionary<string, List<string>> 

은 내가 어떻게 값이 서로 다른 두 개체 사이의 동일 있는지 확인하기 위해 비교를 할 수 있습니까?

예 :

Dictionary<string, List<string>> expected = new Dictionary<string, List<string>>(); 
    expected.Add("CREDIT", new List<string> { "K R EH D IH T" }); 
    expected.Add("CARD", new List<string> { "K AA R D" }); 

    Dictionary<string, List<string>> actual; 
    actual = target.GetTermDictionary(); 
    if (!Enumerable.SequenceEqual(expected, actual)) 
    { 
     Assert.Fail(); 
    } 

내가 SequanceEqual 여기에 좋은 생각하지 않습니다 ..

감사

+0

이 같은 순서로 각 목록의 항목을 필요로 함을? – Rawling

+0

방법이 내장되어 있다고 생각지 않습니다. 여기를보세요 : http://stackoverflow.com/questions/3928822/comparing-2-dictarystring-string-instances –

+0

네, 모든 것이 동일해야하며, 같은 값이어야합니다. – user829174

답변

3
빠른 trues 및 falses에

먼저 바로 가기 :

if(ReferenceEqual(actual, expected)) 
    return true; 
if(actual == null || expected == null || actual.Count != expected.Count) 
    return false; 

이것은 또한 다른 널 (null) 검사가 그렇게 모든게 처리하는 우리 null 참조 예외를 throw 할 수 없습니다. 예제 에서처럼 생성 직후에 카운트를 비교하는 경우이 막대를 모두 건너 뛸 수 있지만,이를 대비하여 별도의 방법으로이 값을 유지해야합니다.

두 사전에 대해 SequenceEqual을 호출 할 수는 없습니다. 이는 동일한 순서로 키를 다시 가져올 수 없기 때문입니다.

return actual.OrderBy(kvp => kvp.Key).SequenceEqual(expected.OrderBy(kvp => kvp.Key)); 

을하지만 두 시퀀스와 동일한 List<string> 값이를 호출 할 DefaultEqualityComparer<List<string>>.Equals() 방법과 동일한 것으로 간주되지 않기 때문에이 작동하지 않습니다 값을 다른 유형으로 우리는 할 수 있습니다.

우리가 SequenceEqual을 사용하는 경우에 IEqualityComparer<KeyValuePair<string, List<string>>>을 만들 수 있지만, Linq가 일반적으로 더 간단하고 간결합니다 (일단 방법을 찾으면). 따라서 :..

요약
List<string> expectedVal; 
foreach(KeyValuePair<string, List<string> kvp in actual) 
{ 
    if(!expected.TryGetValue(kvp.key, out expectedVal) || kvp.Value.Count != expectedVal.Count || !kvp.Value.SequenceEquals(expectedVal)) 
    return false; 

} 
return true; 

변형 평등의 다른 뷰를 해결할 수있는 우리가 같은 것으로 다른 순서의 같은 항목의 두 목록을 고려하기를 원한다면 예를 들어, 우리가 kvp.Value.OrderBy(x => x).SequenceEquals(expectedVal.OrderBy(x => x))를 사용할 수

의 많은 함께 :

if(ReferenceEqual(actual, expected)) 
    return true; 
if(actual == null || expected == null || actual.Count != expected.Count) 
    return false; 
List<string> expectedVal; 
foreach(KeyValuePair<string, List<string> kvp in actual) 
{ 
    if(!expected.TryGetValue(kvp.key, out expectedVal) || kvp.Value.Count != expectedVal.Count || !kvp.Value.SequenceEquals(expectedVal)) 
    return false; 

} 
return true; 

편집 : 그냥 재미를 위해, 방법은 SequenceEquals 사용하는 :

internal class KvpSLSEq : IEqualityComparer<KeyValuePair<string, List<string>>> 
{ 
    public bool Equals(KeyValuePair<string, List<string>> x, KeyValuePair<string, List<string>> y) 
    { 
    return x.Key == y.Key && x.Value.Count == y.Value.Count && x.Value.SequenceEquals(y.Value); 
    } 
    public int GetHashCode(KeyValuePair<string, List<string>> obj) 
    { 
    //you could just throw NotImplementedException unless you'll reuse this elsewhere. 
    int hash = obj.Key.GetHashCode; 
    foreach(string val in obj.Value) 
     hash = hash * 31 + (val == null ? 0 : val.GetHashCode()); 
    } 
} 

를이 우리가 간결 사용할 수 있습니다 완료 :

actual.OrderBy(kvp => kvp.Key).SequenceEqual(expected.OrderBy(kvp => kvp.Key), new KvpSLSEq()); 

을하지만 KvpSLSEq 다른 곳에서 사용할 경우에만 정말 간결입니다 게다가.

1

나는 방법이 지어 생각하지 않지만, 당신이 목록을 비교할 수 있습니다 각 사전 항목 내의 값. 이런 식으로 뭔가 : 여기 Comparing 2 Dictionary<string, string> Instances과 :

// Check actual doesn't contain excess keys 
if (actual.Keys.Count != expected.Keys.Count) 
{ 
    return false; 
} 

foreach(var key in expected.Keys) 
{ 
    if (!actual.ContainsKey(key) || !actual[key].SequenceEqual(expected[key])) 
    { 
     return false; 
    } 
} 

return true; 

여기를보세요 Is there a built-in method to compare collections in C#?

+1

실제에는 초과 키가 없는지 확인해야합니다. – Rawling

+1

고마워, 내 편집 할 것 같아 –

+0

성능 향상을 위해 어느 쪽이든 짧을 경우에는 단축키를 사용합니다. 나는'actual.TryGetValue'를 직접 사용하기 때문에 contains-key 검사를 굴려서 목록을 얻습니다. –

0

당신이 NUnit과 당신이 CollectionAssert.AreEquivalent을 사용할 수를 사용하는 경우,이 질문을 참조하십시오 NUnit: Dictionary Assert

+0

또한 값을 콜렉션으로 처리합니까, 아니면 그냥 List '에 대해 디폴트 'Equals'를 사용할 것입니까? –

관련 문제