컬렉션을 비교하는 기본 제공 방법이 있습니까? 내용을 비교하고 싶습니다. 사전과 IList가 있습니다.

내 Equals 방법에서 두 컬렉션의 내용을 비교하고 싶습니다. 사전과 IList가 있습니다. 이 작업을 수행하는 기본 제공 방법이 있습니까?

편집 : 두 개의 사전과 두 개의 IList를 비교하고 싶기 때문에 평등의 의미가 분명하다고 생각합니다. 두 사전에 동일한 값에 매핑 된 동일한 키가 포함되어 있으면 동일합니다.



답변

Enumerable.SequenceEqual

지정된 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

그것은 당신이 원하는 것을 거의 수행합니다.