Merge two dictionaries Dictionary <string, dictionary <string, object >>

This refers to this question, on how to combine two dictionaries in C #. An elegant Linq solution is presented which is cool.

However, this question pertains to Dictionary<Object1, Object2>

, whereas I have a dictionary where the value is Dictionary<string, Object>

.

I am looking for a tow merge solution Dictionary<string, Dictionary<string, Object>>

with the following requirements:

  • Without duplicating a key in a dictionary, the result of two dictionaries,
  • For each dictionary, I think the KEY grouping might be part of the solution, but after ...

    internal static Dictionary<string, Dictionary<string, object>> OperationDic(Dictionary<string, Dictionary<string, object>> a, Dictionary<string, Dictionary<string, object>> b, string operation)`
        { 
            switch (operation) 
            {
                case "+":
                    var result =  a.Concat(b).GroupBy(d => d.Key).ToDictionary (d => d.Key, d => d.First().Value); 
                    return result;               
                default: 
    
                    throw new Exception("Fail ...");
            }             
        }
    
          

+3


source share


4 answers


I'm not very clear about what you want. This is trying to combine two dictionaries:

    // first copy everything from a
    var result = new Dictionary<string, Dictionary<string, object>>(a);

    // now check to see if we can add stuff from b
    foreach (var entryOuter in b)
    {
      Dictionary<string, object> existingValue;
      if (result.TryGetValue(entryOuter.Key, out existingValue))
      {
        // there already an entry, see if we can add to it
        foreach (var entryInner in entryOuter.Value)
        {
          if (existingValue.ContainsKey(entryInner.Key))
            throw new Exception("How can I merge two objects? Giving up.");
          existingValue.Add(entryInner.Key, entryInner.Value);
        }
      }
      else
      {
        // new entry
        result.Add(entryOuter.Key, entryOuter.Value);
      }
    }

    return result;

      



You might want to add checks for null

. a

, b

and existingValue

(if it exists) maybe null

.

+1


source


try it



var result = a.Concat (b) .GroupBy (c => c.Key) .ToDictionary> (

0


source


 internal static Dictionary<string, Dictionary<string, object>> OperationDic(Dictionary<string, Dictionary<string, object>> a, Dictionary<string, Dictionary<string, object>> b, string operation)
    {
        var result = new Dictionary<string, Dictionary<string, object>>(a);
        switch (operation)
        {
            case "+":                  
            // now check to see if we can add stuff from b
            foreach (var entryOuter in b)
            {
              Dictionary<string, object> existingValue;
              if (result.TryGetValue(entryOuter.Key, out existingValue))
              {
                  Dictionary<string, object> Value = entryOuter.Value;
                  result[entryOuter.Key] = existingValue.Concat(Value).GroupBy(d => d.Key).ToDictionary(d => d.Key, d => d.First().Value);
              }
              else
              {
                // new entry
                result.Add(entryOuter.Key, entryOuter.Value);
              }
            }
            return result;
            default:                    
                throw new Exception("FAIL ...");
        }
    }

      

0


source


The first question you should ask yourself is what type is the result of merging two dictionaries? How can values ​​be combined if they have the same key?

It could be something like this:

public static Dictionary<TKey, IEnumerable<TValue>> Merge<TKey, TValue>(this IDictionary<TKey, TValue> this_, IDictionary<TKey, TValue> other)
{
    return this_.Concat(other).     // IEnumerable<KeyValuePair<TKey, TValue>>
        GroupBy(kvp => kvp.Key).    // grouped by the keys
        ToDictionary(grp => grp.Key, grp => grp.Select(kvp => kvp.Value).Distinct());
}

      

So your two type dictionaries Dictionary<string, Dictionary<string, object>>

will go to Dictionary<string, IEnumerable<Dictionary<string, object>>>

.

However, your values ​​are dictionaries, so you can combine them:

public static Dictionary<TKey, IEnumerable<TValue>> Flatten<TKey, TValue>(IEnumerable<Dictionary<TKey, TValue>> dictionaries)
{
    return dictionaries.SelectMany(d => d.Keys).Distinct().         // IEnumerable<TKey> containing all the keys
        ToDictionary(key => key,
            key => dictionaries.Where(d => d.ContainsKey(key)).     // find Dictionaries that contain the key
                Select(d => d.First(kvp => kvp.Key.Equals(key))).   // select that key (KeyValuePair<TKey, TValue>)
                Select(kvp => kvp.Value));                          // and the value
}

      

This takes IEnumerable<Dictionary<string, object>>

and converts it to Dictionary<string, IEnumerable<object>>

. Now you can call this method for every dictionary value created Merge

.

The calls will be as follows:

Dictionary<string, IEnumerable<Dictionary<string, object>>> result1 = dic1.Merge(dic2);
Dictionary<string, Dictionary<string, IEnumerable<object>>> result2 = dic1.Merge(dic2).ToDictionary(kvp => kvp.Key, kvp => Flatten(kvp.Value));

      

0


source







All Articles