tags:

views:

196

answers:

4

I have two dictionaries like

  Dictionary<String,List<String>> DictOne=new Dictionary<String,List<String>>()
  Dictionary<String,List<String>> DictTwo=new Dictionary<String,List<String>>()

 DictOne


KeyOne     "A"
           "B"

KeyTwo     "C"
           "D"

KeyThree   "X"
           "Y"



DictTwo

Key1      "X"
          "Z"
          "Y"

Key2      "A"


Key3     "C"
         "D"

Key4     "M"
         "N"

i need to compare and merge the two dictonaries regardless of the key and to add the data to the third dictionary

Dictionary<String,List<String>> DictThree=new Dictionary<String,List<String>>()

So the Third Dictionary will contain

DictThree

KeyOne   "A"
         "B"

KeyTwo   "C"
         "D"

KeyThree "X"
         "Y"
         "Z"

Key4     "M"
         "N"

Now i'm iterating through the two dictionaries

Now i'm using like

First i'll take the First list in the DictOne and then search whether the items in the list exist in any list in DictTwo if so perform union operation and then add the resulting list into the third dictionary with the any one key (Key in DictOne or in DictTwo) If the list not exist then add the list along with the key into the third Dictionary. The same will perform for all the lists in DictOne And DictTwo

Is there any way to do this using LINQ

Thanks in advance

A: 

You can do this:

Dictionary<String, List<String>> DictThree = DictOne.Concat(DictTwo);

Or this, if you need to keep it as a Dictionary:

Dictionary<String, List<String>> DictThree = DictOne.Concat(DictTwo).ToDictionary(x => x.Key);
snurre
A: 

You can use this approach:

var dict3 = DictOne
    .Concat(DictTwo)
    .GroupBy(x => x.Key)
    .ToDictionary(x => x.Key, x => x.SelectMany(y => y.Value).ToList());

Of course, if you want to use your own equality comparison, you can serve IEqualityComparer to GroupBy method as second argument.

Matajon
A: 

If what you want is, that you merge all entries of each list by key, you can do it like so:

var dictThree = (from kv in dictOne.Concat(dictTwo)
                  group kv.Value by kv.Key)
   .ToDictionary(k => k.Key, v => v.SelectMany(l => l).Distinct().ToList());

This will yield distinct strings in each list per key.

Robert Giesecke
This is just concatinating the two dictionaries. i need to concatinate based on the value not on key
Pramodh
Well, the question was a bit on the cryptic side, wasn't it? ;-)
Robert Giesecke
+2  A: 

Whew! Quite a challenge. Basically, that fact that they are dictionaries is completely irrelevant, you just need the Dictionary<,>.Values part of each dictionary, so I'm just going to use an array of string arrays (string[][]) for this example.

var group1 = new string[][] { new[] { "A", "B" }, new[] { "C", "D" }, new[] { "X", "Y" } };
var group2 = new string[][] { new[] { "X", "Y", "Z" }, new[] { "A" }, new[] { "C", "D" }, new[] { "M", "N" } };

// For each array in group1, check if it has matching array in group2, if
// it does, merge, otherwise just take the array as is.
var group1Join = from g1 in group1
                 let match = group2.SingleOrDefault(g2 => g1.Intersect(g2).Any())
                 select match != null ? g1.Union(match) : g1;

// Take all the group2 arrays that don't have a matching array in group1 and
// thus were ignored in the first query.
var group2Leftovers = from IEnumerable<string> g2 in group2
                      where !group1.Any(g1 => g2.Intersect(g1).Any())
                      select g2;

var all = group1Join.Concat(group2Leftovers);

EDIT: Corrected code to work in C# 3.0, and not rely on C# 4.0's covariance support.

Allon Guralnek
I have no idea why this answer was voted down as it in fact appears to answer the somewhat unclear question correctly.
Martin Liversage
Even more interesting is the fact that this question has no less than 4 downvotes on four different answers, without a single comment in any of them explaining the reason.
Allon Guralnek
@ Allon Guralnek : all the answers are just concatinating the two dictionaries except yours. And in your answer, IEnumerable<string[]> can not be converted toIEnumerable<IEnumerable<string>>
Pramodh
@Pramodh: The code compiles and runs just fine on .NET 4.
Martin Liversage
@ Martin Liversage : oh.. sorry . I'm using .NET 3.5 . Can you please explain how to do this in 3.5 framework. (Up Voted)
Pramodh
@Pramodh, even if the other answers were obviously incorrect, it is still highly impolite to downvote without you (or someone else) leaving a comment about what's wrong. The issue which prompted a downvote was not obvious to the answerer, even if it was obvious to you (and others). Anyway, I fixed the code to work with C# 3.0.
Allon Guralnek
@ Allon Guralnek:DICTHREE=((from a1 in DICTONE let match = DICTTWO.SingleOrDefault(a2 => a1.Value.Intersect(a2.Value).Any()) select match.Value != null ? new { key = a1.Key, val = a1.Value.Union(match.Value).ToList() } : new { key = a1.Key, val = a1.Value.ToList() }).ToDictionary(X => X.key, Y => Y.val)) .Union(((from a2 in DICTTWO where !DICTONE.Values.Any(a1=>a2.Value.Intersect(a1).Any()) select new { key = a2.Key, val = a2.Value }).ToDictionary(X => X.key, Y => Y.val))).ToDictionary(X => X.Key, Y => Y.Value);
Pramodh
@Pramodh: Huh??
Allon Guralnek
@ Allon Guralnek : its working properly
Pramodh