Rahul Misra
Rahul Misra

Reputation: 679

Merge multiple dictionaries and aggregate values where required

I have three Dictionaries created by calling ToDictionary on a GroupBy projection in LINQ.

var dictionaryOne = _repositoryOne.GetData()
.GroupBy(d => new { d.Property1, d.Property2, d.LocalCcyId})
.ToDictionary(d =>
    new
    {
        d.Key.Property1,
        d.Key.Property2,
        d.Key.LocalCcyId
    },
    v => v.Sum(l => ConvertToUsd(effectiveDate, l.LocalCcyId, l.Amount))); 

var dictionaryTwo = _repositoryTwo.GetData()
.GroupBy(d => new { d.Property1, d.Property2, d.LocalCcyId})
.ToDictionary(d =>
    new
    {
        d.Key.Property1,
        d.Key.Property2,
        d.Key.LocalCcyId
    },
    v => v.Sum(l => ConvertToUsd(effectiveDate, l.LocalCcyId, l.Balance))); 

var dictionaryThree = _repositoryThree.GetData()
.GroupBy(d => new { d.Property1, d.Property2, d.LocalCcyId})
.ToDictionary(d =>
    new
    {
        d.Key.Property1,
        d.Key.Property2,
        d.Key.LocalCcyId
    },
    v => v.Sum(l => ConvertToUsd(effectiveDate, l.LocalCcyId, l.Total))); 

I want to merge these into a dictionary and i) Sum up the values which are in USD & ii) Drop the grouping by LocalCcyId column from the Key

The will be instances to the same key occurring in each of the three dictionaries and I need to aggregate the Sums for all such cases. How do I achieve this in LINQ?

Upvotes: 1

Views: 154

Answers (2)

Enigmativity
Enigmativity

Reputation: 117124

Seems to me that this is all you need:

var finalDictionary =
    dictionaryOne
        .Concat(dictionaryTwo)
        .Concat(dictionaryThree)
        .GroupBy(x => new { x.Key.Property1, x.Key.Property2 }, x => x.Value)
        .ToDictionary(x => new { x.Key.Property1, x.Key.Property2 }, x => x.Sum());

Or, using LINQ syntax (as much as possible) this:

var finalDictionary =
(
    from x in dictionaryOne.Concat(dictionaryTwo).Concat(dictionaryThree)
    group x.Value by new { x.Key.Property1, x.Key.Property2 }
)
    .ToDictionary(x => new { x.Key.Property1, x.Key.Property2 }, x => x.Sum());

Upvotes: 3

NetMage
NetMage

Reputation: 26927

Assuming you are querying a remote datasource, running queries twice over the data or convering to USD twice doesn't seem more efficient then taking the dictionaries and combining them, so that's what I did.

First you need to convert each Dictionary to a new anonymous object having the data you need, then group by the properties summing the values:

var allDictionary = dictionaryOne.Select(kv => new { kv.Key.Property1, kv.Key.Property2, kv.Value })
                                 .Concat(dictionaryTwo.Select(kv => new { kv.Key.Property1, kv.Key.Property2, kv.Value }))
                                 .Concat(dictionaryThree.Select(kv => new { kv.Key.Property1, kv.Key.Property2, kv.Value }))
                                 .GroupBy(k2v => new { k2v.Property1, k2v.Property2 })
                                 .ToDictionary(k2vg => new { k2vg.Key.Property1, k2vg.Key.Property2 }, k2vg => k2vg.Sum(k2v => k2v.Value));

Upvotes: 0

Related Questions