Сравнение двух наборов для новых и отсутствующих ключей - PullRequest
5 голосов
/ 19 сентября 2010

При сравнении двух наборов словаря значений ключей в C #: набор A и набор B, каков наилучший способ перечисления ключей, присутствующих в наборе A, но отсутствующих в наборе B, и наоборот?

Например:

A = { 1, 2, 5 }
B = { 2, 3, 5 }

Сравнение B с A, отсутствующие ключи = {1} и новые ключи = {3}.

Используя Dictionary<...,...> объекты, можно перечислить все значения в B и проверитьпротив набора A с использованием A.ContainsKey(key);, но кажется, что должен быть лучший способ, который может включать в себя отсортированный набор?

Ответы [ 4 ]

7 голосов
/ 19 сентября 2010

Мне известны два встроенных способа создания различий между наборами.

1) Enumerable.Except

Создает разность установок двухпоследовательности для сравнения значений по умолчанию.

Пример:

IEnumerable<int> a = new int[] { 1, 2, 5 };
IEnumerable<int> b = new int[] { 2, 3, 5 };

foreach (int x in a.Except(b))
{
    Console.WriteLine(x);  // prints "1"
}

2a) HashSet .ExceptWith

Удаляет все элементы в указанной коллекции из текущего объекта HashSet .

HashSet<int> a = new HashSet<int> { 1, 2, 5 };
HashSet<int> b = new HashSet<int> { 2, 3, 5 };

a.ExceptWith(b);

foreach (int x in a)
{
    Console.WriteLine(x);  // prints "1"
}

2b) HashSet .SymmetricExceptWith

Изменяет текущий объект HashSet , чтобы он содержал только элементы, которые присутствуют либо в этом объекте, либо в указанной коллекции, но не в обоих.

HashSet<int> a = new HashSet<int> { 1, 2, 5 };
HashSet<int> b = new HashSet<int> { 2, 3, 5 };

a.SymmetricExceptWith(b);

foreach (int x in a)
{
    Console.WriteLine(x);  // prints "1" and "3"
}

Если вам что-то нужноболее производительный, вам, вероятно, придется свернуть свой собственный тип коллекции.

2 голосов
/ 19 сентября 2010

Использование SortedDictionary: логика A.Except(A.Intersect(B)).

Не беспокойтесь о производительности, пока не решите, что это проблема ваших наборов данных.

0 голосов
/ 19 сентября 2010

Так что здесь есть несколько ответов, которые будут работать. Но ваш оригинальный вопрос лучше всего рассмотреть в двух частях:

В) При сравнении двух наборов словаря значений ключей в C #: установите A и установите B, каков наилучший способ перечисления ключей, присутствующих в наборе A, но отсутствующих в наборе B, и наоборот? Используя объекты Dictionary <..., ...>, можно перечислить все значения в B и проверить набор A, используя A.ContainsKey (key) ;, ...

Если вы начинаете с двух словарей, это может быть лучшим подходом. Чтобы сделать что-либо еще, потребуется создать копию ключей из обоих наборов, что сделает большинство альтернатив более дорогостоящими.

В) ... но кажется, что должен быть лучший способ, который может включать отсортированный набор?

Да, это можно сделать с помощью отсортированного списка достаточно легко. Создайте две вставки списка, отсортированные с помощью BinarySearch, затем обойдите набор 1 во время поиска набора 2 и т.д.

Смотрите следующие операции дополнения и вычитания из SetList: http://csharptest.net/browse/src/Library/Collections/SetList.cs#234

0 голосов
/ 19 сентября 2010

Вы можете использовать метод Except.

Dictionary<string, string> dic1 = new Dictionary<string, string>() { { "rabbit", "hat" }, { "frog", "pond" }, { "cat", "house" } };
Dictionary<string, string> dic2 = new Dictionary<string, string>() { { "rabbit", "hat" }, { "dog", "house"}, {"cat", "garden"}};

    var uniqueKeys = dic1.Keys.Except(dic2.Keys);

    foreach (var item in uniqueKeys)
    {
        Console.WriteLine(item);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...