0

So I have a concurrent dictionary defined as such

 ConcurrentDictionary<string, ConcurrentDictionary<string, ConcurrentDictionary<string, SomeObject>>>();

I know that seems a little convoluted but the structure is valid...

Now my problem is that I have say x number of instances of these dictionaries for x different sources and for statistical purposes they need to be merged/amalgamated/aggregated into one single dictionary of the same structure...

Anyone any ideas on the best approach? I know I could create a new dictionary of the same structure; loop through each of the dictionaries to be amalgamated and at each level checking the new dictionary for those keys etc and adding or updating based on the result of that determination...

But that seems slightly unwieldy to me... any LINQ geniuses out there that could lend a hand?

[Note - I just made one important edit - the output dictionary is of the exact same structure as the input dictionaries]

Dave Lawrence
  • 3,843
  • 2
  • 21
  • 35
  • 2
    Can you give an example of input data and the desired result? – dtb Nov 19 '12 at 11:42
  • 2
    @dtb... is that really needed? The structure of the input and output data is easily inferred from the dictionary structure itself. Not actually trying to be a smartass there... The content of the data is not relevant – Dave Lawrence Nov 19 '12 at 11:46
  • 1
    Maybe it's just me... but from the structure of your dictionaries I have no idea what the aggregated result should look like. – dtb Nov 19 '12 at 11:54
  • The structure of the aggregated result is the exact same of that of all the input dictionaries... I'm trying to merge dictionaries of the same structure into one superset dictionary of the exact same structure... – Dave Lawrence Nov 19 '12 at 11:58
  • 1
    'aggregate' usually means to reduce the number of dimensions of a data structure by one, e.g., `listOfInts.Sum()` or `listOfListOfString.SelectMany(x => x)`. But apparently you don't want to aggregate a single instance of your data structure but merge multiple instances. That put me off track. Have you considered using a `ConcurrentDictionary, SomeObject>`? That would make things much easier. – dtb Nov 19 '12 at 12:01
  • @dtb.. fair point; I was struggling a little with the correct terminology. The tuple key is interesting... it's a toss up between reworking what's already implemented or trying to aggregate these dictionaries – Dave Lawrence Nov 19 '12 at 12:11

1 Answers1

1

LINQ doesn't help here, as you don't want to query a collection but manipulate one.

As said in the comments above, using a ConcurrentDictionary<Tuple<string, string, string>, SomeObject> would simplify things a bit. You could do the following then:

using MyDict = ConcurrentDictionary<Tuple<string, string, string>, SomeObject>;

MyDict Merge(IEnumerable<MyDict> dicts)
{
    MyDict result = new MyDict();

    foreach (var dict in dicts)
    {
        foreach (var kvp in dict)
        {
            result.AddOrUpdate(
                kvp.Key,        // If the key does not exist, add the value;
                kvp.Value,      // otherwise, combine the two values.
                (key, value) => Combine(value, kvp.Value)
            );
        }
    }

    return result;
}
dtb
  • 213,145
  • 36
  • 401
  • 431
  • I achieved what I wanted using a combination of foreach and AddOrUpdate; however I'm going to accept your answer as a great alternative. Cheers. – Dave Lawrence Nov 19 '12 at 13:58