2012-01-13 3 views
11

Есть ли метод LINQ, чтобы найти разницу между двумя родовыми словарями?
То же, что и в this question, но с родовыми словарями.найти разницу между двумя словарями

+0

Вы можете использовать 'AsEnumerable' чтобы«конвертировать»свой словарь в' IEnumerable ', а затем использовать решение, предложенное в связанном вопросе. Поскольку KeyValuePair является структурой, он должен сравнивать по значению. – Heinzi

+1

Вам не нужно 'AsEnumerable', так как это абсолютно не конвертируется. Это только удобный метод для ограничения методов intellisense для 'IEnumerable ' расширений, а также позволяет использовать расширения 'IEnumerable ' на объектах, которые также реализуют 'IQueryable ' без необходимости кастования. – Nuffin

+2

'dic1.Except (x => dic2.Contains (x)). Union (dic2.Except (x => dic1.Contais (X));', вам нужен лучший метод? –

ответ

21
var diff = dicOne.Except(dicTwo).Concat(dicTwo.Except(dicOne)); 
+1

этот метод сравнивает только ключи? –

+2

@ bto.rdz Нет, как ключ, так и значение. – Magnus

+0

Отлично но не забудьте проверить на 'null' –

0

что-то вроде этого?

var dicOne = new Dictionary<string, string>(){ {"asdf", "asdf"}, {"few","faew"}}; 
var dicTwo = new Dictionary<string, string>(){ {"asdf", "asdf"}}; 

var unContained = dicOne.Where(x => !dicTwo.Contains(x)); 
+2

Не включает эти элементы только в' dictTwo', но не в 'dictOne'. –

1

Если производительность важна, вы можете использовать хэш-поиск словарного класса и получить увеличение скорости. Я взял тестовый сценарий словаря с 1 миллионом записей, глубоко скопировал его и сделал 10 исправлений (5 записей удалены, 5 добавлено) в копию. [У меня была задача сделать это, включая поиск изменений в данных, а затем нажатие только изменений на другую функцию.]

С LINQ (см. Ответ Магнуса) время, прошедшее в соответствии с секундомером, составляло 3600 мсек. При простом сравнении с использованием Dictionary.Contains() время, прошедшее, составляло 600 мс. Окружающая среда была сообществом Visual Studio 2017 в режиме отладки тестового жгута ConsoleApp на том же компьютере.

Ваш пробег может отличаться, и у вас может быть небольшое количество строк, поэтому это может иметь значение, но для больших словарей он платит за использование функциональности поиска класса Dictionary.

public static void DiffDictionaries<T, U>(
     Dictionary<T, U> dicA, 
     Dictionary<T, U> dicB, 
     Dictionary<T, U> dicAdd, 
     Dictionary<T, U> dicDel) 
    { 
     // dicDel has entries that are in A, but not in B, 
     // ie they were deleted when moving from A to B 
     diffDicSub<T, U>(dicA, dicB, dicDel); 

     // dicAdd has entries that are in B, but not in A, 
     // ie they were added when moving from A to B 
     diffDicSub<T, U>(dicB, dicA, dicAdd); 
    } 

    private static void diffDicSub<T, U>(
     Dictionary<T, U> dicA, 
     Dictionary<T, U> dicB, 
     Dictionary<T, U> dicAExceptB) 
    { 
     // Walk A, and if any of the entries are not 
     // in B, add them to the result dictionary. 

     foreach (KeyValuePair<T, U> kvp in dicA) 
     { 
      if (!dicB.Contains(kvp)) 
      { 
       dicAExceptB[kvp.Key] = kvp.Value; 
      } 
     } 
    } 
Смежные вопросы