Reputation: 693
class Key { string s; int i; }
Given a Dictionary<Key,int>
I want a new Dictionary<string,int>
that is a mapping of the minimum dictionary value for each Key.s over all keys.
I feel like this should be easy but I just can't get it.
Thanks
clarification:
var dict = new Dictionary<Key,int>();
dict.Add(new Key("a", 123), 19);
dict.Add(new Key("a", 456), 12);
dict.Add(new Key("a", 789), 13);
dict.Add(new Key("b", 998), 99);
dict.Add(new Key("b", 999), 11);
and I want to produce the dictionary:
"a" -> 12
"b" -> 11
hope that helps.
Upvotes: 0
Views: 2237
Reputation: 22876
A more generic method to skip the Lookup
that is created by .GroupBy
:
public static Dictionary<K, V> aggregateBy<T, K, V>(
this IEnumerable<T> source,
Func<T, K> keySelector,
Func<T, V> valueSelector,
Func<V, V, V> aggregate,
int capacity = 0,
IEqualityComparer<K> comparer = null)
{
var dict = new Dictionary<K, V>(capacity, comparer);
foreach (var t in source)
{
K key = keySelector(t);
V accumulator, value = valueSelector(t);
if (dict.TryGetValue(key, out accumulator))
value = aggregate(accumulator, value);
dict[key] = value;
}
return dict;
}
Sample use:
var dict = new Dictionary<Tuple<string,int>, int>();
dict.Add(Tuple.Create("a", 123), 19);
dict.Add(Tuple.Create("a", 456), 12);
dict.Add(Tuple.Create("a", 789), 13);
dict.Add(Tuple.Create("b", 998), 99);
dict.Add(Tuple.Create("b", 999), 11);
var d = dict.aggregateBy(p => p.Key.Item1, p => p.Value, Math.Min);
Debug.Print(string.Join(", ", d)); // "[a, 12], [b, 11]"
Upvotes: 1
Reputation: 17223
I'm not clear on exactly what you're trying to do, but you can do a mapping from one dictionary to another with .Select(...
and/or .ToDictionary(...
For example:
Dictionary<Key, int> original = ...
Dictionary<string, int> mapped = original.ToDictionary((kvp) => kvp.Key.s, (kvp) => kvp.Key.i);
If you improve your question to be more clear, I'll improve my answer.
EDIT: (question was clarified)
var d = dict.GroupBy(kvp => kvp.Key.s).ToDictionary(g => g.Key, g => g.Min(k => k.Value));
You want to group by the key s
property, then select the minimum of the dictionary value as the new dictionary value.
Upvotes: 3