Lemuel Nitor
Lemuel Nitor

Reputation: 333

GroupBy a Dictionary based on key

I have a Dictionary<string,string> that I want to group. Here are some sample key/value pairs

==========================
| Key            | Value |
==========================
| A_FirstValue   | 1     |
| A_SecondValue  | 2     |
| B_FirstValue   | 1     |
| B_SecondValue  | 2     |
==========================

Now, I want to group it according to the first letter or word in the key before the first instance of the character '_'

So, the final result will be Dictionary<string, Dictionary<string, string>>. For the example above the result will be:

A -> A_FirstValue, 1
     A_SecondValue, 2

B -> B_FirstValue, 1
     B_SecondValue, 2

Is this even possible? Anyone who could help me please?

Thanks.

Upvotes: 7

Views: 11274

Answers (3)

Thinking Sites
Thinking Sites

Reputation: 3542

yourDictionary
    .GroupBy(g => g.Key.Substring(0, 1))
    .ToDictionary(k => k.Key, v => v.ToDictionary(k1 => k1.Key, v1 => v1.Value));

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1502116

Well, you could use:

var dictionary = dictionary.GroupBy(pair => pair.Key.Substring(0, 1))
       .ToDictionary(group => group.Key,
                     group => group.ToDictionary(pair => pair.Key,
                                                 pair => pair.Value));

The group part will give you an IGrouping<string, KeyValuePair<string, string>>, and the subsequent ToDictionary will convert each group of key/value pairs back into a dictionary.

EDIT: Note that this will always use the first letter. For anything more complicated, I would probably write a separate ExtractFirstWord(string) method and call that in the GroupBy lambda expression.

Upvotes: 9

vansimke
vansimke

Reputation: 974

Here is what I came up with. Should had some error handling to ensure that an _ exists in the Key, but should get you started.

        var source = new Dictionary<string, int>();

        source.Add("A_FirstValue", 1);
        source.Add("A_SecondValue", 2);
        source.Add("B_FirstValue", 1);
        source.Add("B_SecondValue", 3);

        var dest = new Dictionary<string, Dictionary<string, int>>();

        foreach (KeyValuePair<string, int> entry in source) {
            string prefix = entry.Key.Split('_')[0];
            if (!dest.ContainsKey(prefix)) {
                dest.Add(prefix, new Dictionary<string, int>());
            }

            dest[prefix].Add(entry.Key, entry.Value);

        }

Upvotes: 0

Related Questions