Click here to Skip to main content
15,895,142 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hi Friends,

I have dictionary with below structure
C#
Dictionary<int, List<double>> dicendingvalue = new Dictionary<int, List<double>>();


I need to sum all the List<double>> values with in the dictionary of the same index and need to get final result.

for Example
dic key: 1 , values: { 2, 3, 5 }
key: 2 , values: { 5, 8, 4 }

Result {7,11,9}
Posted
Updated 15-May-16 20:56pm
v2
Comments
CPallini 6-May-16 7:20am    
And who stops you in doing it?
BillWoodruff 6-May-16 12:57pm    
"my list contain 25 entries and it may grow as well so how can i hard cord the index"

Will you always have the same number of values in each List of Doubles ? If that's guaranteed then writing the code is much simpler.

See code example below.
jinesh sam 7-May-16 5:50am    
Thanks Bill :) In my case number of values in each List of Doubles will be same

To be honest, I wouldn't use Linq - it really wouldn't be very efficient, as you'd have to call Sum three times, which means three loops in reality.
You could abuse Aggregate:
C#
Dictionary<int, List<double>> dicendingvalue = new Dictionary<int, List<double>>();
dicendingvalue.Add(0, new List<double>() { 0, 0, 0 });
dicendingvalue.Add(1, new List<double>() { 2, 3, 5 });
dicendingvalue.Add(2, new List<double>() { 5, 8, 4 });
var x = dicendingvalue.Values.Aggregate((a, b) => { a[0] += b[0]; a[1] += b[1]; a[2] += b[2]; return a; });
Which will overwrite the first entry with the totals, but requires only one pass.
Not exactly readable though!

Me? I'd use a foreach...
 
Share this answer
 
Comments
jinesh sam 6-May-16 7:48am    
Thanks for posting the answer.
Getting error says: ValueCollection' does not contain a definition for 'Aggregate' dictionary
one more problem here, my list contain 25 entries and it may grow as well so how can i hard cord the index
OriginalGriff 6-May-16 8:29am    
Seriously, use a foreach, :laugh: Trying to do this with Linq is just going to get unwieldy and pretty much unmaintainable - and it will change!
Provided the count of each dictionary Values should be same.

try this.
C#
List<double> sum = new List<double>();
          int count = dictionary.ToList().First().Value.Count;
          for (int i = 0; i < count; i++)
          {
              double temp = 0;
              foreach (List<double> items in dictionary.Values)
                  temp += items[i];
              sum.Add(temp);

          }


updated solution:
the below code will take care, irespective of items count in each value of dictionary.
C#
List<double> sum = new List<double>();
           int maxCount = dictionary.Values.ToList().Max(k => k.Count);
           for (int i = 0; i < maxCount; i++)
           {
               double temp = 0;
               foreach (List<double> items in dictionary.Values)
                   if (i < items.Count)
                       temp += items[i];
               sum.Add(temp);

           }
 
Share this answer
 
v4
Comments
BillWoodruff 6-May-16 14:57pm    
+5 You are on the right track here. I'm going to post a variation that uses similar logic.
Karthik_Mahalingam 6-May-16 23:47pm    
Thanks bill, i have updated my solution, which will take care of the items count in each dictionary value.
BillWoodruff 7-May-16 0:12am    
But, keep in mind that we don't know if creating the totals this way is what is actually required here.

Minor point: your code does more work when it loops on the maximum number of items possible rather than the number of actual values (list of double) present in the Dictionary ValuesCollection.
Karthik_Mahalingam 7-May-16 0:20am    
Yes agree, initially i had this thought, since he showed up with few data, it wont impact much i feel :)
who knows, the OP should be very clear in mentioning requirement in the question.
most of the questions are like, they provide half inputs and rest we have to assume :)
BillWoodruff 7-May-16 6:12am    
I think the important thing is that we point out to the OP what they may need to think about carefully, and what we'd need to know to give a really definitive, or better, answer. As well as ... oh, yes ... the 'codez' :) cheers, Bill
A slightly different way of doing what Karthik demonstrates here, showing the use of the 'yield iterator pattern:
C#
Dictionary<int, List<double>> intdbl = new Dictionary<int, List<double>>
{
    {1, new List<double>{1.0,2.0,3.0}},
    {2, new List<double>{56.0,21.0,323.0}}
};

IEnumerable<double> listSums(List<List<double>> lstValues)
{
    // no lists : quit
    if (lstValues.Count == 0) yield break;

    // like Karthik I assume that the first list
    // item count is what to use ...
    int repcount = lstValues[0].Count;

    // no items : quit
    if (repcount == 0) yield break;

    // select only those lists that have the same number of items
    var okayvalues = lstValues.Where(lst => lst.Count == repcount);

    // this should not happen ... but ...
    if (okayvalues.Count() == 0) 
    {
        yield break;
    }

    for (int i = 0; i < repcount; i++)
    {
        yield return
            (okayvalues.Select(lst => lst[i]).Sum());
    }
}


// test in some method or EventHandler
// IEnumerable<double> is returned
var test = listSums(intdbl.Values.ToList());</double>
The issue of what you can reliably assume is true about the state of the data you deal with here is ... critical. The above example would work with Dictionaries where the values (lists of double) are of any size, but, you can see that if you base the number of values to use on just the first list ... you have made an assumption that may come back to haunt you.

Assuming that you always want to have a number of "totals" equal to the size of the largest dictionary value (list of doubles), actually makes it simpler, imho, to program:

C#
Dictionary<int, List<double>> intdbl = new Dictionary<int, List<double>>
{
    {1, new List<double>{1.0,2.0,3.0}},
    {2, new List<double>{56.0,21.0,323.0}},
    {3, new List<double>{22.23, 12.435, 99.332, 120.453, 0.993}}
};

// test in a method or EventHandler

// get the size of the largest list in 'Value Collection
int maxlistsize = intdbl.Values.ToList()
    .Select(itm => itm.Count).Max();

// allocate a new list of doubles with 'maxlistsize
// and fill it with 0.0's
List<double> totals = new List<double>(maxlistsize);
totals.AddRange(Enumerable.Repeat(0d, maxlistsize));

foreach (List<double> dbllist in intdbl.Values)
{
    for (int i = 0; i < dbllist.Count; i++)
    {
        totals[i] += dbllist[i];
    }
}

// Result:

> ? totals
Count = 5
    [0]: 79.23
    [1]: 35.435
    [2]: 425.332
    [3]: 120.453
    [4]: 0.993</double></double></double>
The question remains however: what is your requirement here for structural consistency of the data ? When your code is used, what can you assume about the data, and what do those assumptions require to do in code to prevent errors and get "meaningful" results.
 
Share this answer
 
Comments
Karthik_Mahalingam 6-May-16 23:51pm    
5, for the idea [Max()] to handle different count in each dictionary value.
I have implemented that in my updated solution.
Thank you.
BillWoodruff 16-May-16 3:54am    
Thanks, Karthik !
George Swan 7-May-16 1:33am    
Very neat, Bill, 5
BillWoodruff 7-May-16 6:10am    
Thanks, George !
Maciej Los 15-May-16 13:17pm    
5ed!
In addition to already posted answers, i'd like to add Linq solution (even if it may cause performance issues for huge amount of data).

Try this:
C#
Dictionary<int, List<double>> dicendingvalue = new Dictionary<int, List<double>>();
dicendingvalue.Add(1, new List<double>() { 2, 3, 5 }); //3 items!
dicendingvalue.Add(2, new List<double>() { 5, 8, 4, 10}); //4 items!

var resultlist = dicendingvalue
				.SelectMany(x=>x.Value.Select((a,b) => new{index=b, value=a}))
				.GroupBy(x=>x.index)
				.Select(grp=>new{index = grp.Key, sov = grp.Sum(a=>a.value)})
				.ToList();

Using Tuple[^]:
C#
var resultlist1 = dicendingvalue
				.SelectMany(x=>x.Value.Select((a,b) => Tuple.Create(b, a)))
				.GroupBy(x=>x.Item1)
				.Select(grp=>new{index = grp.Key, sov = grp.Sum(a=>a.Item2)})
				.ToList();

As you can see, the count of items in List<double> may differ, but the result is always good ;)
index  sov 
0       7 
1       11 
2       9 
3       10 
 
Share this answer
 
v3
Comments
Karthik_Mahalingam 16-May-16 2:58am    
5, Master of Linq :)
Maciej Los 16-May-16 3:00am    
Thank you, Karthik.
Karthik_Mahalingam 16-May-16 3:14am    
welcome :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900