c# dictionaries intersect

19,910

Solution 1

You could do in this way:

resultDict =  primaryDict.Keys.Intersect(secondaryDict.Keys)
                              .ToDictionary(t => t, t => primaryDict[t]);

or, alternatively:

resultDict =  primaryDict.Where(x => secondaryDict.ContainsKey(x.Key))
                         .ToDictionary(x => x.Key, x => x.Value);

the latter maybe is slightly more efficient because avoids the creation of a throw-away collection (the one generated by the Intersect method) and does not require a second access-by-key to primaryDict.

EDIT (as per comment) :

resultDict =  
primaryDict.Where(x => secondaryDict.ContainsKey(x.Key))
           .ToDictionary(x => x.Key, x => x.Value + secondaryDict[x.Key]);

Solution 2

You can still use primaryDict within your Linq statement since you are creating a new dictionary, which only gets assigned to your variable once it is created:

resultDict = primaryDict.Keys
                        .Intersect(secondaryDict.Keys)
                        .ToDictionary(t => t, primaryDict[t]);

Solution 3

Untested:

resultDict = primaryDict.Keys.Intersect(secondaryDict.Keys).ToDictionary(t => t.Key, primaryDict[t.Key]);
Share:
19,910
Stewart Basterash
Author by

Stewart Basterash

Updated on June 06, 2022

Comments

  • Stewart Basterash
    Stewart Basterash almost 2 years

    I have a question about Linq / Lambda and the following issue:

    I have two dictionaries, primary and secondary... These two dictionaries are defined as Key=string, Value=int. I need to trim down the primary dictionary if the KEYS intersect with secondary dictionary.

    i.e.:

    primaryDict = ["thing1", 33] ["thing2", 24] ["thing3", 21] ["thing4", 17] ["thing5", 12]
    
    secondaryDict = ["thing1", 22] ["thing3", 20] ["thing4", 19] ["thing7", 17] ["thing9", 10]
    
    resultDict = ["thing1", 33] ["thing3", 21] ["thing4", 17]
    

    My attempt:

    resultDict = primaryDict.Keys.Intersect(secondaryDict.Keys).ToDictionary(t => t.Key, t.Value);
    

    This obviously does not work because the primaryDict.Keys.Intersect is returning a list of keys... how would I reestablish a new dictionary, or pair down the primary dictionary? Any help would be appreciated.

  • Dave Bish
    Dave Bish about 12 years
    I think the last version is much better, as I don't think treating the dictionary as an IEnumerable will leverage the Dictionary, and will run in O(n) time.
  • Stewart Basterash
    Stewart Basterash about 12 years
    That worked great for what I'm doing... I used the second solution and everything is working as expected. You rock Dave!
  • Stewart Basterash
    Stewart Basterash about 12 years
    As a follow up... is it possible to sum the values in this same expression?
  • digEmAll
    digEmAll about 12 years
    @StewartBasterash: The values in primaryDict with the ones in secondaryDict having the same keys?
  • Stewart Basterash
    Stewart Basterash about 12 years
    Yes... I am capturing and evaluating data across different domains. The different dictionaries maintain the data for a given domain... The key indicates an element within that domain, and the value is how it was presented in that domain... I am attempting to do some additional calculation... I need to do statistical analysis on a given element (key), across multiple domains (dictionary), based on values for each key... I hope this makes sense?
  • Stewart Basterash
    Stewart Basterash about 12 years
    Got it... That makes sense... sorry for my ignorance... I am new to writing Lambda in .NET, but I'm really loving this stuff for the things that I do with data mining...
  • digEmAll
    digEmAll about 12 years
    @StewartBasterash: don't worry, LINQ and lambda expressions can be pretty difficult at the beginning ;)
  • SRJ
    SRJ over 7 years
    how can i do this based on values.?? Intersection is working but i want to convert it to dictionary.. So .ToDictionary(t => t, t => primaryDict[t]); part gives error
  • digEmAll
    digEmAll over 7 years
    @SRJ: if you're intersecting values you can't use primaryDict[value], but maybe I didn't get your problem... anyway I suggest you to open a new question
  • theonlygusti
    theonlygusti over 2 years
    Is this faster than linear? How fast is this?