Raaz - 1 year ago 88

C# Question

I am looking for a help in solving an exercise using C#, LINQ.

I have a dictionary with

`DateTime`

`decimal`

Input dictionary:

`01/31/2015 100`

02/28/2015 100

03/31/2015 100

;

; and so on

;

01/31/2017 200

02/28/2017 200

03/31/2017 200

Output should be as below:

`01/31/2015 100`

02/28/2015 200

03/31/2015 300

;

;

01/31/2017 200

02/28/2017 400

03/31/2017 600

Here is what I did so far. It computes the total but not resetting for the next year. In Jan 2016, it adds the value of Jan to the previous sum. I guess a GroupBy is needed before I write aggregate().

`public static IDictionary<DateTime, decimal?> RunningTotal_NotResettingForNextYear(this IDictionary<DateTime, decimal?> inputDictionary)`

{

IDictionary<DateTime, decimal?> runningTotalDictinary =

new Dictionary<DateTime, decimal?>(inputDictionary.Count);

inputDictionary.Aggregate((decimal?)0, (sum, value) =>

{

sum = sum + value.Value;

runningTotalDictinary.Add(value.Key, sum);

return sum;

});

return runningTotalDictinary;

}

Answer Source

The missing part is `GroupBy`

method.

- First, group inputDictionary by year.
- Then compute the new value for each item with an accumulator (F# inspired) group by group
- Merge groups into one liste.
- Create the new dictionary.

Then the final code :

```
var newDico = inputDictionary.OrderBy(i => i.Key).GroupBy(i => i.Key.Year).SelectMany(
group =>
{
decimal? accumulator = 0;
return
group.Select(
element =>
new { Key = element.Key, Value = (accumulator += element.Value)});
}).ToDictionary(accGroupItem => accGroupItem.Key, accGroupItem => accGroupItem.Value);
```

Or with a temp accumulator dictionary :

```
var dicoAcc = inputDictionary
.Select(i => i.Key.Year)
.Distinct()
.ToDictionary(year => year, _ => (decimal?)0);
var newDico = inputDictionary
.ToDictionary(i => i.Key, i => dicoAcc[i.Key.Year] += i.Value);
```