Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
TheGreatCornholio
1235 / 715 / 283
Регистрация: 30.07.2015
Сообщений: 2,392
1

Реализация интерфейса IEqualityComparer для HashSet<Dictionary<string, string>>

07.09.2015, 00:57. Просмотров 2330. Ответов 4


Код выдает "2", что, логично, а хотелось бы, чтобы выдавал "1", так как содержание словарей одинаковое.
Подскажите, пожалуйста, желательно, максимально быструю и удобную реализацию интерфейса IEqualityComparer
для сравнения двух Dictionary<string,string>.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
            HashSet<Dictionary<string, string>> hs = new HashSet<Dictionary<string, string>>(/*здесь нужен правильный  IEqualityComparer*/);
 
            Dictionary<string, string> dic = new Dictionary<string, string>();
            dic.Add("Номер", "111");
            
            Dictionary<string, string> dic2 = new Dictionary<string, string>();
            dic2.Add("Номер", "111");
 
            
 
            hs.Add(dic);
            hs.Add(dic2);
 
            MessageBox.Show(hs.Count.ToString());
И вообще, я на правильном пути?

Добавлено через 40 минут
Пока остановился на этом, вроде работает.
Покритикуйте, кому не жалко, код.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
        public class DictionaryStrStrComparer : IEqualityComparer<Dictionary<string,string>>
        {
           
            public bool Equals(Dictionary<string,string> D1, Dictionary<string,string> D2)
            {
              return GetHashCode(D1)==GetHashCode(D2);  
            }
 
          
            public int GetHashCode(Dictionary<string,string> D)
            {
                string AllFromDict = string.Join("", D.Keys.ToArray()) + string.Join("", D.Values.ToArray());             
                
                return AllFromDict.GetHashCode();
            }
        }
 
        HashSet<Dictionary<string, string>> hs = new HashSet<Dictionary<string, string>>(new DictionaryStrStrComparer());
 
        Dictionary<string, string> dic = new Dictionary<string, string>();
        dic.Add("Номер", "111");
            
        Dictionary<string, string> dic2 = new Dictionary<string, string>();
        dic2.Add("Номер", "111");
 
            
 
        hs.Add(dic);
        hs.Add(dic2);
 
        MessageBox.Show(hs.Count.ToString());
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.09.2015, 00:57
Ответы с готовыми решениями:

Dictionary<string, Dictionary<string, string>>
Ребята тут есть силачи ? Мне нужно решить эту проблему static void Main(string args)...

List<string, string, string> есть ли в C# что-то подобное?
Мне надо добавить в List не только имя файла, но и некоторые строки из этого файла. Т.е. например,...

Разность множеств для Dictionaty<string, string>
Здравствуйте! есть два словаря Dictionary&lt;string, string&gt; fixBlockNormalizeStrings и...

Как архивировать Dictionary<string, Dictionary<string, decimal[,]>>
Программа периодически создает Dictionary&lt;string, Dictionary&lt;string, decimal&gt;&gt; большого размера....

4
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.09.2015, 17:33 2
Лучший ответ Сообщение было отмечено Woldemar89 как решение

Решение

Woldemar89, всё плохо Приведение к строкам вообще печаль. Можно же сделать намного проще:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class DictionaryStrStrComparer : IEqualityComparer<Dictionary<string, string>>
{
 
    public bool Equals(Dictionary<string, string> first, Dictionary<string, string> second)
    {
        return GetHashCode(first) == GetHashCode(second);
    }
 
 
    public int GetHashCode(Dictionary<string, string> dictionary)
    {
        return dictionary.Aggregate(0, (current, pair) => current ^ ((pair.Key.GetHashCode()*397) ^ pair.Value.GetHashCode()));
    }
}
Добавлено через 6 минут
Можно для скорости даже распараллелить без проблем:
C#
1
2
3
4
5
6
7
8
9
public int GetHashCode(Dictionary<string, string> dictionary)
{
    return dictionary.AsParallel()
                     .Aggregate(() => 0,
                                (current, pair) =>
                                current ^ ((pair.Key.GetHashCode()*397) ^ pair.Value.GetHashCode()),
                                (x, y) => x ^ y,
                                x => x);
}
Добавлено через 1 минуту
Ой. А Equals у вас конечно жесть Существуют коллизии, а вы будете их считать одним и тем же...

итоговая реализация должна быть какой-то такой:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    public class DictionaryStrStrComparer : IEqualityComparer<Dictionary<string, string>>
    {
 
        public bool Equals(Dictionary<string, string> first, Dictionary<string, string> second)
        {
            return first.SequenceEqual(second);
        }
 
 
        public int GetHashCode(Dictionary<string, string> dictionary)
        {
            return dictionary.AsParallel()
                             .Aggregate(() => 0,
                                        (current, pair) =>
                                        current ^ ((pair.Key.GetHashCode()*397) ^ pair.Value.GetHashCode()),
                                        (x, y) => x ^ y,
                                        x => x);
        }
    }
1
TheGreatCornholio
1235 / 715 / 283
Регистрация: 30.07.2015
Сообщений: 2,392
07.09.2015, 17:42  [ТС] 3
Psilon, Премного благодарен!
Поясните только каким образом в коде избегаете коллизий?
Что происходит здесь и причем здесь 397?
C#
1
return dictionary.Aggregate(0, (current, pair) => current ^ ((pair.Key.GetHashCode()*397) ^ pair.Value.GetHashCode()));
0
Master of Orion
Эксперт .NET
6079 / 4935 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.09.2015, 17:44 4
Лучший ответ Сообщение было отмечено Woldemar89 как решение

Решение

Woldemar89, тем, что я не по хэшу сравниваю, а по значению. 397 - просто достаточно большое простое число, обеспечивающее хорошее перемешивание бит при xor'е. Можно взять и какое-нибудь другое.
1
TheGreatCornholio
1235 / 715 / 283
Регистрация: 30.07.2015
Сообщений: 2,392
07.09.2015, 17:46  [ТС] 5
Цитата Сообщение от Psilon Посмотреть сообщение
обеспечивающее хорошее перемешивание бит при xor'е.
Ну, углубляться мы не будем
Спасибо за помощь!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.09.2015, 17:46

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Какие функции выполняет private readonly dictionary <string; string> и marker.BackColor?
Подскажите пожалуйста, какие функции выполняет private readonly dictionary &lt;string; string&gt; и ...

Обработать словарь типа Dictionary<string, string> и на выходе получить ступенчатый массив
Всем здравствуйте! Я только начинаю познавать программирование (около месяца).Поэтому прошу...

Данные загрузить в коллекцию Dictionary<string,string> скопировать в списки, перемешать и сформировать ключ
здравствуйте) в файле есть вопросы и ответы. данные из файла нужно загрузить в коллекцию...

List<Dictionary<String, String>> - заполнить данными datagridview
Есть переменная List&lt;Dictionary&lt;String, String&gt;&gt;, мне необходимо заполнить ей datagridview. Как...

Как выдернуть данные из Dictionary<string,string>.Enumerator?
Есть библиотека xNet. Когда делаешь http запрос вот так: var ss =...

Заполнить Dictionary<string, list<string>> из файла ресурсов
Всем привет! У меня появилась проблема, мне нужно заполнить Dictionary&lt;string, list&lt;string&gt;&gt; из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.