내 Equals 방법에서 두 컬렉션의 내용을 비교하고 싶습니다. 사전과 IList가 있습니다. 이 작업을 수행하는 기본 제공 방법이 있습니까?
편집 : 두 개의 사전과 두 개의 IList를 비교하고 싶기 때문에 평등의 의미가 분명하다고 생각합니다. 두 사전에 동일한 값에 매핑 된 동일한 키가 포함되어 있으면 동일합니다.
답변
지정된 IEqualityComparer (T)를 사용하여 요소를 비교하여 두 시퀀스가 같은지 확인합니다.
목록과 사전을 직접 비교할 수는 없지만 사전의 값 목록을 목록과 비교할 수는 있습니다.
답변
다른 사람들이 제안하고 언급했듯이 SequenceEqual
순서에 민감합니다. 이를 해결하기 위해 키를 기준으로 사전을 정렬하고 (고유하므로 정렬은 항상 안정적 임)을 사용할 수 있습니다 SequenceEqual
. 다음 표현식은 내부 순서와 상관없이 두 사전이 동일한 지 확인합니다.
dictionary1.OrderBy(kvp => kvp.Key).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key))
편집 : Jeppe Stig Nielsen이 지적한 것처럼 일부 객체에는와 IComparer<T>
호환되지 않는 객체가있어 IEqualityComparer<T>
잘못된 결과를 생성합니다. 이러한 객체와 함께 키를 사용하는 경우 IComparer<T>
해당 키에 올바른 키를 지정해야 합니다. 예를 들어,이 문제를 나타내는 문자열 키를 사용하면 올바른 결과를 얻으려면 다음을 수행해야합니다.
dictionary1.OrderBy(kvp => kvp.Key, StringComparer.Ordinal).SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key, StringComparer.Ordinal))
답변
언급 한 외에 SequenceEqual 어느
두 목록의 길이가 같고 해당 요소가 비교 자에 따라 동일하게 비교되는 경우 true
(기본 비교기, 즉 overriden 일 수 있음 Equals()
)
.Net4 에는 ISet
객체에 SetEquals 가 있음을 언급 할 가치가 있습니다.
요소의 순서와 중복 요소를 무시합니다.
따라서 객체 목록을 원하지만 특정 순서로 정렬 할 필요는없는 경우 ISet
(와 같은 HashSet
)이 올바른 선택 일 수 있습니다.
답변
Enumerable.SequenceEqual 메소드를 살펴보십시오.
var dictionary = new Dictionary<int, string>() {{1, "a"}, {2, "b"}};
var intList = new List<int> {1, 2};
var stringList = new List<string> {"a", "b"};
var test1 = dictionary.Keys.SequenceEqual(intList);
var test2 = dictionary.Values.SequenceEqual(stringList);
답변
.NET 모음을 비교할 수있는 강력한 도구가 없습니다. 아래 링크에서 찾을 수있는 간단한 솔루션을 개발했습니다.
http://robertbouillon.com/2010/04/29/comparing-collections-in-net/
순서에 관계없이 평등 비교를 수행합니다.
var list1 = new[] { "Bill", "Bob", "Sally" };
var list2 = new[] { "Bob", "Bill", "Sally" };
bool isequal = list1.Compare(list2).IsSame;
항목이 추가 / 제거되었는지 확인합니다.
var list1 = new[] { "Billy", "Bob" };
var list2 = new[] { "Bob", "Sally" };
var diff = list1.Compare(list2);
var onlyinlist1 = diff.Removed; //Billy
var onlyinlist2 = diff.Added; //Sally
var inbothlists = diff.Equal; //Bob
사전의 어떤 항목이 변경되었는지 확인할 수 있습니다.
var original = new Dictionary<int, string>() { { 1, "a" }, { 2, "b" } };
var changed = new Dictionary<int, string>() { { 1, "aaa" }, { 2, "b" } };
var diff = original.Compare(changed, (x, y) => x.Value == y.Value, (x, y) => x.Value == y.Value);
foreach (var item in diff.Different)
Console.Write("{0} changed to {1}", item.Key.Value, item.Value.Value);
//Will output: a changed to aaa
답변
Enumerable.SequenceEqual 메소드 (매일 무언가를 배우고 있습니다 …)에 대해 몰랐지만 확장 메소드를 사용하는 것이 좋습니다. 이 같은:
public static bool IsEqual(this List<int> InternalList, List<int> ExternalList)
{
if (InternalList.Count != ExternalList.Count)
{
return false;
}
else
{
for (int i = 0; i < InternalList.Count; i++)
{
if (InternalList[i] != ExternalList[i])
return false;
}
}
return true;
}
흥미롭게도 SequenceEqual에 대해 2 초가 걸린 후에 Microsoft가 내가 설명한 기능을 구축 한 것 같습니다.
답변
이것은 귀하의 질문에 직접 대답하지는 않지만 MS의 TestTools와 NUnit은
CollectionAssert.AreEquivalent
그것은 당신이 원하는 것을 거의 수행합니다.