Adding an int value of a dictionary within a dictionary

Viewed 155

I have a dictionary and I am trying to add the value that is inside another dictionary.

Below I have the dictionary:

    Dictionary<string, Dictionary<string, int>> dic = new Dictionary<string, Dictionary<string, int>>(){
    {
        "first", new Dictionary<string, int>()
        {
            { "test1", 21 },
            { "test2", 1 },
            { "test3", 21 },
            { "test4", 122 },
        }
    },

    {
        "second", new Dictionary<string, int>()
        {
            { "test1", 33 },
            { "test2", 22 },
            { "test3", 2 },
            { "test4", 1 },
        }
    },

    {
        "third", new Dictionary<string, int>()
        {
            { "test1", 41 },
            { "test2", 31 },
            { "test3", 12 },
            { "test4", 11 },
        }
    },
};

I want to add all the values ​​where I have the key "test1".

I've tried it this way:

int totalTest1 = dic.Sum(x => x.Value.Where(l => l.Key == "test1").SelectMany(z => z.Value));

But it is giving error

Severity Code Description Project File Line Suppression Status
Error CS0411 The type arguments of the method "Enumerable.SelectMany <TSource, TResult> (IEnumerable <TSource>, Func <TSource, IEnumerable <TResult>>)" cannot be inferred based on usage. Try to explicitly specify the type arguments. CalculadoraLancamento C: \ Users \ sergi \ source \ repos \ CalculadoraLancamento \ CalculadoraLancamento \ Form1.cs 183 Active
3 Answers

You probably don't need to do a LINQ query on the inner dictionary since you're simply accessing a value in the dictionary by key:

int totalTest1 = dic.Sum(x => x.Value["test1"]);

And if you're not certain that the inner dictionary will always contain the specified key, you can check before accessing:

int totalTest1 = dic.Sum(x => x.Value.TryGetValue("test1", out int result) ? result : 0);

The query that you're looking for is this:

int totalTest1 =
    dic
        .SelectMany(x => x.Value)
        .Where(z => z.Key == "test1")
        .Select(z => z.Value)
        .Sum();

The SelectMany is flattening the outer dictionary into an IEnumerable<KeyValuePair<string, int>> and that's easy to filter on the Key and then Sum on the value.

With your given sample data, I get 95.

Another variation that gets 95

Console.WriteLine(dic.SelectMany(x => x.Value)
                     .Where(x => x.Key == "test1")
                     .Sum(x => x.Value)); // put criteria into SUM

This is actually performs a little better vs using TryGetValue

Related