45

I'm having a low-brainwave day... Does anyone know of a quick & elegant way to transform a Dictionary so that the key becomes the value and vice-versa?

Example:

var originalDictionary = new Dictionary<int, string>() {
    {1, "One"}, {2, "Two"}, {3, "Three"}
};

becomes

var newDictionary = new Dictionary<string, int>();
// contents:  
// { 
//    {"One", 1}, {"Two", 2}, {"Three", 3} 
// };
Morgoth
  • 4,935
  • 8
  • 40
  • 66
code4life
  • 15,655
  • 7
  • 50
  • 82

4 Answers4

96

Use ToDictionary ?

orignalDictionary.ToDictionary(kp => kp.Value, kp => kp.Key);

This works because IDictionary<TKey,TElement>; is also an IEnumerable<KeyValuePair<TKey,TElement>>;. Just be aware that if you have duplicate values, you will get an exception.

In case you have duplicate values, you will need to decide on what to do with them. One simple way would be to ignore duplicates by grouping on Value first, then make the dictionary.

originalDictionary
.ToLookup(kp => kp.Value)
.ToDictionary(g => g.Key, g => g.First().Key);
Selman Genç
  • 100,147
  • 13
  • 119
  • 184
driis
  • 161,458
  • 45
  • 265
  • 341
  • When I use your example involving `ToLookup`, I get "'System.Linq.IGrouping>' does not contain a definition for 'Value'". I had to use `ToDictionary` alone on my dictionary. – Sarah Vessels Sep 27 '10 at 18:26
  • @Sarah, sounds like you are using ToLookup on an already grouped sequence. – driis Sep 27 '10 at 19:51
  • I was specifying the generic types `` that didn't match the mapping, for instance: `originalDic.ToDictionary(...)` vs lets the system inferring the types `originalDic.ToDictionary(...)` that helps me. If you want to specify it, you have to do something like `originalDic.ToDictionary, T, R>(...)` in this case will be `originalDic.ToDictionary, string, int>(...)` – Jaider Oct 06 '15 at 15:48
  • `public static Dictionary ToDictionary(...)` – Jaider Oct 06 '15 at 15:54
9

Here you are:

var reversed = orignalDictionary.ToDictionary(el => el.Value, el => el.Key);

Giorgi
  • 30,270
  • 13
  • 89
  • 125
0

Is there a particular context in the application where you have 1-to-1 relation or is it global? If the latter, you may want to check out a BiDirectional Dictionary.

Community
  • 1
  • 1
Tormod
  • 4,551
  • 2
  • 28
  • 50
0

I agree with the answers provided, however you should consider and make the change in your program to actually set up with the <key, value> instead of making this change after.

VoodooChild
  • 9,776
  • 8
  • 66
  • 99
  • Agreed in principle. But the problem is that the original dictionary serves a specific purpose, and rather than make another soap call, it's more convenient to transform what I have for another library that need the same info but with the key/value reversed. – code4life Jun 03 '10 at 20:00