Dictionary "Grouping" by value
I have a dictionary: Dictionary<int,int> . I want to get a new dictionary where the keys of the original dictionary are indicated as List<int> . Here is what I mean:
var prices = new Dictionary<int,int>(); prices contains the following data:
1 100 2 200 3 100 4 300 I want to get IList<Dictionary<int,List<int>>> :
int List<int> 100 1,3 200 2 300 4 How can i do this?
Here is my answer. When dictionaries become large, you are more likely to find GroupBy () extension methods are less efficient than you would like, because they provide many guarantees that you do not need, such as saving order.
public static class DictionaryExtensions { public static IDictionary<TValue,List<TKey>> Reverse<TKey,TValue>(this IDictionary<TKey,TValue> src) { var result = new Dictionary<TValue,List<TKey>>(); foreach (var pair in src) { List<TKey> keyList; if (!result.TryGetValue(pair.Value, out keyList)) { keyList = new List<TKey>(); result[pair.Value] = keyList; } keyList.Add(pair.Key); } return result; } } And an example usage in LinqPad:
void Main() { var prices = new Dictionary<int, int>(); prices.Add(1, 100); prices.Add(2, 200); prices.Add(3, 100); prices.Add(4, 300); // Dump method is provided by LinqPad. prices.Reverse().Dump(); } You can use GroupBy and then overload Func<TSource, TKey>, Func<TSource, TElement> Enumerable.ToDictionary :
var d = prices.GroupBy(x => x.Value).ToDictionary(x => x.Key, x => x.ToList()); In the particular case, when we use the .NET framework 2.0, we can do the following:
var prices = new Dictionary<int, int>(); prices.Add(1, 100); prices.Add(2, 200); prices.Add(3, 100); prices.Add(4, 300); Dictionary<int, List<int>> grouping = new Dictionary<int, List<int>>(); var enumerator = prices.GetEnumerator(); while (enumerator.MoveNext()) { var pair = enumerator.Current; if (!grouping.ContainsKey(pair.Value)) grouping[pair.Value] = new List<int>(); grouping[pair.Value].Add(pair.Key); }