Сравните два словаря на предмет равенстваC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Сравните два словаря на предмет равенства

Сообщение Anonymous »

С помощью C# я хочу сравнить два словаря с
  • ключами в виде строки и
  • значения как список целых чисел.
Я предполагаю, что два словаря равны, если
  • они оба имеют одинаковые ключи
  • и для каждого ключа каждое значение в списке целых чисел одинаково (оба не обязательно в одном и том же порядке). >
Я использую оба ответа из этого и этого связанного вопроса, но оба они не прошли мой набор тестов для тестовых функций DoesOrderKeysMatter и DoesOrderValuesMatter.
Мой набор тестов:

Код: Выделить всё

public static List GetList(int x, int y)
{
List list = new List();
list.Add(x);
list.Add(y);
return list;
}

public static Dictionary GetDict1()
{
Dictionary dict1 = new Dictionary();
dict1.Add("a", GetList(1,2));
dict1.Add("b", GetList(3,4));
return dict1;
}

public static Dictionary GetDict2()
{
Dictionary dict2 = new Dictionary();
dict2.Add("b", GetList(3,4));
dict2.Add("a", GetList(1,2));
return dict2;
}

Тестовый класс

Код: Выделить всё

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;

namespace UnitTestProject1
{
[TestClass]
public class ProvideReportTests
{
[TestMethod]
public void AreSameDictionariesEqual()
{
// arrange
Dictionary dict1 = GetDict1();
// act
bool dictsAreEqual = false;
dictsAreEqual = AreDictionariesEqual(dict1, dict1);
// assert
Assert.IsTrue(dictsAreEqual, "Dictionaries are not equal");
}

[TestMethod]
public void AreDifferentDictionariesNotEqual()
{
// arrange
Dictionary dict1 = GetDict1();
Dictionary dict2 = new Dictionary();
// act
bool dictsAreEqual = true;
dictsAreEqual = AreDictionariesEqual(dict1, dict2);
// assert
Assert.IsFalse(dictsAreEqual, "Dictionaries are equal");
}

[TestMethod]
public void DoesOrderKeysMatter()
{
// arrange
Dictionary dict1 = GetDict1();
Dictionary dict2 = GetDict2();
// act
bool dictsAreEqual = false;
dictsAreEqual = AreDictionariesEqual(dict1, dict2);
// assert
Assert.IsTrue(dictsAreEqual, "Dictionaries are not equal");
}

[TestMethod]
public void DoesOrderValuesMatter()
{
// arrange
Dictionary dict1 = GetDict1();
Dictionary dict2 = new Dictionary();
dict2.Add("a", GetList(2,1));
dict2.Add("b", GetList(3,4));
// act
bool dictsAreEqual = false;
dictsAreEqual = AreDictionariesEqual(dict1, dict2);
// assert
Assert.IsTrue(dictsAreEqual, "Dictionaries are not equal");
}

private bool AreDictionariesEqual(Dictionary dict1, Dictionary dict2)
{
return dict1.Keys.Count == dict2.Keys.Count &&
dict1.Keys.All(k => dict2.ContainsKey(k) &&
object.Equals(dict2[k], dict1[k]));

// also fails:
//    return dict1.OrderBy(kvp => kvp.Key).SequenceEqual(dict2.OrderBy(kvp => kvp.Key));
}
}
}
Как правильно сравнивать словари такого типа? Или в моем (правда, неуклюже написанном) TestSuite есть ошибка?
Обновление
Я пытаюсь включить Ответ Серви в моем наборе тестов, как показано ниже, но я получаю некоторые ошибки (подчеркнуты красной волнистой линией в Visual Studio):
  • Код: Выделить всё

    SetEquals
    в методе `Equals говорит: "не содержит определения для SetEquals, принимающего первый аргумент типа Generic.List.
  • В словарях равныDictionaryComparer — это тип, но он используется как переменная.`

    Код: Выделить всё

    namespace UnitTestProject1
    {
    [TestClass]
    public class ProvideReportTests
    {
    [TestMethod]
    // ...  same as above
    
    private bool AreDictionariesEqual(Dictionary dict1, Dictionary dict2)
    {
    DictionaryComparer(new ListComparer() dc = new DictionaryComparer(new ListComparer();
    return dc.Equals(dict1, dict2);
    
    }
    
    }
    
    public class DictionaryComparer :
    IEqualityComparer
    {
    private IEqualityComparer valueComparer;
    public DictionaryComparer(IEqualityComparer valueComparer = null)
    {
    this.valueComparer = valueComparer ?? EqualityComparer.Default;
    }
    public bool Equals(Dictionary x, Dictionary y)
    {
    if (x.Count != y.Count)
    return false;
    if (x.Keys.Except(y.Keys).Any())
    return false;
    if (y.Keys.Except(x.Keys).Any())
    return false;
    foreach (var pair in x)
    if (!valueComparer.Equals(pair.Value, y[pair.Key]))
    return false;
    return true;
    }
    
    public int GetHashCode(Dictionary obj)
    {
    throw new NotImplementedException();
    }
    }
    
    public class ListComparer : IEqualityComparer
    {
    private IEqualityComparer valueComparer;
    public ListComparer(IEqualityComparer valueComparer = null)
    {
    this.valueComparer = valueComparer ?? EqualityComparer.Default;
    }
    
    public bool Equals(List x, List y)
    {
    return x.SetEquals(y, valueComparer);
    }
    
    public int GetHashCode(List obj)
    {
    throw new NotImplementedException();
    }
    }
    
    public static bool SetEquals(this IEnumerable first, IEnumerable second, IEqualityComparer comparer)
    {
    return new HashSet(second, comparer ?? EqualityComparer.Default)
    .SetEquals(first);
    }
    
    }
    


Подробнее здесь: https://stackoverflow.com/questions/217 ... r-equality
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»