Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a list to a dictionary and sum up values using linq

Tags:

c#

linq

I have list i.e. List<Field>. This Field class contains a code and a value properties among other fields and I would like to be able to use linq in order to sum up all the values for the same code.

I know I could loop through my list and add this to a dictionary using the following code, but I'm sure there has to be a cleaner way to do this:

if (totals.ContainsKey(code))
{
  totals[code] += value;
}
else
{
  totals.Add(code, value);
}

Any ideas?

I found something similar, but this applied to a list> which isn't what I have:

var result = Sales.SelectMany(d => d) // Flatten the list of dictionaries
             .GroupBy(kvp => kvp.Key, kvp => kvp.Value) // Group the products
             .ToDictionary(g => g.Key, g => g.Sum());

from this article [Sum amount using Linq in <List<Dictionary<string, int>>]Sum amount using Linq in <List<Dictionary<string, int>>

Any ideas? I could always change my code to have a Dictionary<string, Field> but I'm sure there has to be a way to do this with a list and linq.

Thanks.

I have list i.e. List<Field>. This Field class contains a code and a value properties among other fields and I would like to be able to use linq in order to sum up all the values for the same code.

I know I could loop through my list and add this to a dictionary using the following code, but I'm sure there has to be a cleaner way to do this:

if (totals.ContainsKey(code))
{
  totals[code] += value;
}
else
{
  totals.Add(code, value);
}

Any ideas?

I found something similar, but this applied to a list> which isn't what I have:

var result = Sales.SelectMany(d => d) // Flatten the list of dictionaries
             .GroupBy(kvp => kvp.Key, kvp => kvp.Value) // Group the products
             .ToDictionary(g => g.Key, g => g.Sum());

from this article [Sum amount using Linq in <List<Dictionary<string, int>>]Sum amount using Linq in <List<Dictionary<string, int>>

Any ideas? I could always change my code to have a Dictionary<string, Field> but I'm sure there has to be a way to do this with a list and linq.

Thanks.

UPDATE:

Sorry, I think I omitted an important section in regards to the above. The list is contained within another list i.e. List> myitemList; which will contain other irrelevant fields which may require further filtering. I'm not sure???

NOTE: Sorry formatting is messed up once again!

To give a bit of context to this:

Item1 (of type List)

Item Name Value

(Item 1) Type 1 (Item 2) Description Test (Item 3) Code A (Item 4) Net 100.00

Item2 (of type List)

Item Name Value

(Item 1) Type 2 (Item 2) Description Test1 (Item 3) Code B (Item 4) Net 95.55

Item3 (of type List)

Item Name Value

(Item 1) Type 2 (Item 2) Description Test2 (Item 3) Code A (Item 4) Net 35.95

As you can see each list of type List contains 4 Field entries where my Field is defined with Name (String) and Value (Object)

Each of these list is then added to a main list. So I need to loop through the main list and in turn I want to end up with a dictionary what will contain the "Code" and sum of "Net" for each list. So at the end, I should just end up with

A, 135.95 B, 95.55

I don't know if the above make sense. I hope it does!

UPDATE

The fact that I'm dealing with a list> actually didn't make a different as I actually wanted to sum up one list at the time, so provide answer is correct! Thank you!

like image 867
Thierry Avatar asked Nov 05 '13 17:11

Thierry


3 Answers

The code that you posted is almost what you need - for using it on the list you need to simplify it slightly:

var result = myList                             // No flattening
    .GroupBy(x => x.Code)                       // Group the items by the Code
    .ToDictionary(g => g.Key, g => g.Sum(v => v.Value)); // Total up the values
like image 156
Sergey Kalinichenko Avatar answered Oct 24 '22 09:10

Sergey Kalinichenko


var list = new List<Field>
{
    new Field { Code = "A", Value = 10 },
    new Field { Code = "A", Value = 20 },
    new Field { Code = "B", Value = 30 },
};

var dic = list
    .GroupBy(z => z.Code)
    .ToDictionary(z => z.Key, z => z.Sum(f => f.Value));
like image 35
ken2k Avatar answered Oct 24 '22 09:10

ken2k


You can do:

Dictionary<string, int> dictionary = 
            list.GroupBy(r => r.ID)
                .ToDictionary(grp => grp.Key, grp => grp.Sum(r => r.Value));

Considering you have class like:

public class MyClass
{
    public string ID { get; set; }
    public int Value { get; set; }
}
like image 20
Habib Avatar answered Oct 24 '22 09:10

Habib