Dictionary from other dictionary grouping by object value field using linq

I have a Dictionary<ulong,Terminal> called TeminalDictionary in my program, where Terminal has the next props:

public class Terminal
{
    public string TAC { get; set; }
    public string Name { get; set; }
    public string Model { get; set; }
    public string OS { get; set; }
    public string Manufacturer { get; set; }
    public uint Freq { get; set; }
 }

So, for that Dictionary, I want to make another one Dictionary<string,ulong> suming all the frequencies for every Manufacturer, so the dictionary key is Terminal.Manufacturer and the value is Sum(Terminal.Freq) with the same Manufacturer.

I tried this expression:

var pieDictionary = TerminalDictionary
    .GroupBy(x => x.Value.Manufacturer)
    .ToDictionary(g => g.Sum(v => v.Value.Freq));

but it says that I'm trying to add an element with the same key, so I'm a little bit lost...

Regards!

Upvotes: 2

Views: 343

Answers (2)

Tim Schmelter
Tim Schmelter

Reputation: 460208

Can i suggest you a different approach? You could use a Lookup<tkey,tval>:

var manufacturerFreqs = TeminalDictionary.Values
    .ToLookup(t => t.Manufacturer, t => (int)t.Freq);
int freq = manufacturerFreqs["Manufacturername"].Sum();

A lookup is similar to a dictionary and is as efficient, but it allows "duplicate" keys since the value is an IEnumerable<TVal> so you can query it.

So it's possible to store the complete object as element and get the sum of Freq anyway:

var manufacturerTerminals = TeminalDictionary.Values.ToLookup(t => t.Manufacturer);
int freq = manufacturerTerminals["Manufacturername"].Sum(t => (int)t.Freq);

This makes this collection more flexible, reusable and powerful.

MSDN:

A Lookup<TKey, TElement> resembles a Dictionary<TKey, TValue>. The difference is that a Dictionary<TKey, TValue> maps keys to single values, whereas a Lookup<TKey, TElement> maps keys to collections of values. You can create an instance of a Lookup by calling ToLookup on an object that implements IEnumerable<T>.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502126

You just need to provide the key in the new dictionary as well, which in your case is the key of the group. Given that you don't appear to need the keys within the original dictionary, I'd write this as:

var pieDictionary = TerminalDictionary.Values
    .GroupBy(x => x.Manufacturer)
    .ToDictionary(g => g.Key, g => g.Sum(v => v.Freq));

Upvotes: 3

Related Questions