I have a variable of type Dictionary
I want to convert it to a Lookup.
Not an answer for the question, but I think this is related information and should be posted here.
There is some edge cases you should take into account. All of them about items of dictionary, which have key, but don't have value.
This is expected behavior. Dictionary and Lookup designed for different purposes.
var dic = new Dictionary<bool, IEnumerable<bool?>> { [true] = null };
var lookup = dic.ToLookup();
Assert.AreEqual(1, dic.Count);
Assert.AreEqual(0, lookup.Count);
Assert.IsTrue(dic.ContainsKey(true));
Assert.IsFalse(lookup.Contains(true));
Assert.IsFalse(dic.ContainsKey(false));
Assert.IsFalse(lookup.Contains(false));
dic[false] -> Exception
lookup[false] -> bool?[0]
Same as Jon's method, but avoiding the creation of an anonymous type:
var lookup = dictionary
.SelectMany(p => p.Value, Tuple.Create)
.ToLookup(p => p.Item1.Key, p => p.Item2);
Already a few answers here, but putting this here for reference. This flips a dictionary with a list of values, to having those values as the keys of look up list.
var myLookup = myDict.SelectMany(p => p.Value,
(pair, id) => Tuple.Create(id, pair.Key))
.ToLookup(p => p.Item1, p => p.Item2);
Annotated
var myLookup = myDict.SelectMany(
// specify that the select many is to be based off the Value which is a list of items
p => p.Value,
// Using the individual items from that list, create a tuple of that item and the dictionary key it was under
(pair, id) => Tuple.Create(id, pair.Key))
// use the item as the lookup key, and put the original dictionary key (that
// had that value underneath them) in the list of lookup values.
.ToLookup(p => p.Item1, p => p.Item2);
How about:
var lookup = dictionary.SelectMany(pair => pair.Value,
(pair, Value) => new { pair.Key, Value })
.ToLookup(pair => pair.Key, pair => pair.Value);
It does feel like a little bit of a waste doing this when the dictionary already has all the information grouped appropriately, but I can't see a simple way round that. Of course you could implement ILookup<TKey, TValue> yourself with a wrapper around the dictionary...