Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

finding difference between two dictionaries

Is there a LINQ method to find difference between two generic dictionaries?
Same as in this question, but with generic dictionaries.

like image 401
dragan.stepanovic Avatar asked Jan 13 '12 13:01

dragan.stepanovic


People also ask

Can you compare two dictionaries in Python?

You can use the == operator, and it will work. However, when you have specific needs, things become harder. The reason is, Python has no built-in feature allowing us to: compare two dictionaries and check how many pairs are equal.

How do I check if two dictionaries are equal in Python?

Check if two nested dictionaries are equal in Python To do this task, we are going to use the == operator and this method will help the user to check whether the two given dictionaries are equal or not.


2 Answers

var diff = dicOne.Except(dicTwo).Concat(dicTwo.Except(dicOne));
like image 165
Magnus Avatar answered Sep 28 '22 04:09

Magnus


If performance is important, you might want to use the hash lookup of the Dictionary class and get a speed improvement. I took a test scenario of a dictionary with 1 million entries, deep-copied it and made 10 edits (5 entries removed, 5 added) to the copy. [I had a task to do that involved looking for changes in data, and then pushing only the changes through to another function.]

With LINQ (see Magnus' answer) time elapsed according to Stopwatch was 3600ms approx. With simple comparison using Dictionary.Contains(), time elapsed was 600ms approx. Environment was Visual Studio 2017 Community in Debug mode for a ConsoleApp test harness, on same machine.

Your mileage may vary, and you might have a modest number of lines, so it might not matter, but for larger dictionaries it pays to use the lookup functionality of the Dictionary class.

In the example below dicA and dicB are the two similar dictionary objects that you want to difference. dicAdd is the dictionary of items that A has, but which are missing from B. dicDel is the reverse, items that B contains, but A does not. Try using with some very simple test dictionaries where you know what to expect, and it should become clear how to use.

    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;
            }
        }
    }
like image 31
Steve Hibbert Avatar answered Sep 28 '22 05:09

Steve Hibbert