tags:

views:

81

answers:

1

I need to compare two dictionaries and to update another dictionary with unmatched items

The two dictionaries are like

Dictionary<String, List<String>> DICTONE = new Dictionary<string, List<String>>();
Dictionary<string, List<String>> DICTTWO = new Dictionary<string, List<String>>();

And the contents

DICTONE["KEY1"]="A"
                "B"
                "C"

DICTONE["KEY2"]="D"
                "E"
                "F"

DICTTWO["KEY1"]="A"
                "B"
                "Z"

DICTTWO["KEY3"]="W"
                "X"
                "Y"

The third dictionary has a class instance as value

Dictionary<String, MyClass> DICTRESULT = new Dictionary<string, MyClass>();

and the class is like

class MyClass
{
    public List<string> Additional = null;
        public List<string> Missing = null; 

    public MyClass()
        {
            Additional = new List<string>();
            Missing = new List<string>();
        }
        public MyClass(List<string> p_Additional, List<string> p_Missing)
        {
            Additional = p_Additional;
            Missing = p_Missing;
        }
}

The scenerio is

  1. If an item in in DICTONE and NOT in DICTTWO the add the item to MISSING list in the RESULTDICT
  2. If an item in in DICTTWO and NOT in DICTTONE the add the item to ADDITIONAL list in the RESULTDICT

the expected answer is

DICTRESULT["KEY1"]=ADDITIONAL LIST ---> "Z"
                   MISSING LIST    ---> "C"

DICTRESULT["KEY2"]=ADDITIONAL LIST ---> ""
                   MISSING LIST    ---> "D"
                                        "E"
                                        "F"
DICTRESULT["KEY3"]=ADDITIONAL LIST ---> ""
                   MISSING LIST    ---> "W"
                                        "X"
                                        "Y"

is there any way to do this using LINQ

+2  A: 

Well, here's an attempt, assuming first and second are the dictionaries in question.

var items = from key in first.Keys.Concat(second.Keys).Distinct()
            let firstList = first.GetValueOrDefault(key) ?? new List<string>()
            let secondList = second.GetValueOrDefault(key) ?? new List<string>()
            select new { Key = key,
                         Additional = secondList.Except(firstList),
                         Missing = firstList.Except(secondList) };
var result = items.ToDictionary(x => x.Key,
                                x => new MyClass(x.Additional, x.Missing));

This is completely untested, mind you. I haven't even tried to compile it. It also requires an extra extension method:

public static TValue GetValueOrDefault<TKey, TValue>
    (this IDictionary<TKey, TValue> dictionary,
     TKey key)
{
    TValue value;
    dictionary.TryGetValue(key, out value)
    return value;
}
Jon Skeet