1

Hi I have two Dictionaries and I need to find a way to join them together.Here are the two dictionary types.

IDictionary<string, byte[]> dictionary1
IDictionary<IFileShareDocument, string> dictionary2

Out of this two dictionaries I have to create a third dictionary that will look like this

IDictionary<IFileShareDocument, byte[]> dictionary3

Both dictionaries have the exact same number of items and the string property of both them is the linking point.

What I would like is to be able to write something that would do somethign like this:

dictionary1.value join with dictionary2.key
where dictionary1.key == dictionary2.value

This statement should result in dictionary3.

Is there any way I can achieve this I can not seem to find a way to do this?

aleczandru
  • 5,319
  • 15
  • 62
  • 112

3 Answers3

5
var dictionary3 =
    dictionary1
        .Join(dictionary2, x => x.Key, x => x.Value, (x, y) => new { x, y })
        .ToDictionary(a => a.y.Key, a => a.x.Value);
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
King King
  • 61,710
  • 16
  • 105
  • 130
2

Here's a way to do it using the LINQ query syntax, with join (this compiles to roughly the same thing as @KingKing's solution):

IDictionary<IFileShareDocument, byte[]> dictionary3 =
    (from item1 in dictionary1
     join item2 in dictionary2 on item1.Key equals item2.Value
     select new { item2.Key, item1.Value })
         .ToDictionary(x => x.Key, x => x.Value);

Note that the above is greatly preferred to this example using from and where, because it is more efficient. I'm including this here because if you're like me (more familiar with SQL, which would convert something like this to a join automatically), this poor way might be the first one that comes to mind:

IDictionary<IFileShareDocument, byte[]> dictionary3 =
    (from item1 in dictionary1
     from item2 in dictionary2
     where item1.Key == item2.Value
     select new { item2.Key, item1.Value })
         .ToDictionary(x => x.Key, x => x.Value);
Tim S.
  • 55,448
  • 7
  • 96
  • 122
  • The first solution will perform *dramatically* worse than the second solution. A Join is O(N + M), a Cartesian Product is O(N * M). There isn't any real advantage to the Cartesian Product at all, assuming you actually want a Join, so long as the relevant keys already have sensible hash code and equality implementations (which they do). – Servy Aug 28 '13 at 14:30
  • @Servy thanks for pointing that out; I've swapped my solutions and included a note saying why `join` is better. – Tim S. Aug 28 '13 at 14:32
  • Why include the other solution at all? It has no advantages, only disadvantages. What is to be gained by having it there? – Servy Aug 28 '13 at 14:33
  • 1
    For the same reason that counterexamples and anti-patterns can be worth mentioning. Someone like me who is more familiar with SQL than LINQ might be tempted to do it that way (that's all I included at first), without realizing that LINQ isn't intelligent enough to convert that into an intelligent Join. – Tim S. Aug 28 '13 at 14:35
2

Would this work for you?

var result =
    dictionary2
        .ToDictionary(x => x.Key, x => dictionary1[x.Value]);
Enigmativity
  • 113,464
  • 11
  • 89
  • 172