title: Combine/Add dictionaries in a list when the values for two dictionary are equal in C#
body: <p>I want to extract a processed list of dictionary values (<code>List&lt;Dictionary&lt;String,Object&gt;&gt;</code>) from a raw list dictionary values(<code>List&lt;Dictionary&lt;String,Object&gt;&gt;</code>) .</p>
  
  <p>The Raw dict may contain String/Numeric Value</p>
  
  <p>Eg:</p>
  
  <pre><code>Dictionary&lt;String, Object&gt; rawListDict = new Dictionary&lt;String, Object&gt;();
  rawListDict.Add("Product","Apple");
  rawListDict.Add("Region", "West");
  rawListDict.Add("Profit", 90);
  </code></pre>
  
  <p><strong>Raw List:</strong> </p>
  
  <p>Apple West 90</p>
  
  <p>Apple East 10</p>
  
  <p>Apple West 80</p>
  
  <p><strong>Processed List :</strong> </p>
  
  <p>Apple West 170</p>
  
  <p>Apple East 10</p>
  
  <p>Consider a list with dictionaries having same product and region, I want a single dict by adding the "Profit" when the "Product" &amp; "Region" are same. (i.e) List of Dictionaries with similar items grouped as single dictionary without any duplicates</p>
  
  <p>Note : Raw list can grow beyond 30K entries. :-(</p>
  
  <p>I have implemented a logic by Brute-force Technique and its consuming a lot of memory and time .Is there any way to do it in LINQ style or any other approach to reduce time and memory ?</p>
  
  <p><strong>Edit : I am preferring Dictionary since the number of members/keys are only known at the run time.</strong></p>
  
  <p>Code I have Implemented : </p>
  
  <pre><code>                    //Get fields which could be used for combining values
                      var nonMeasurableFields = report.datagrid_fields.
                          Where(field =&gt; field.dataType.Equals(ImFieldDatatype.STRING_VALUE) || field.dataType.Equals(ImFieldDatatype.DATE_VALUE)).
                          Select(field =&gt; field.name).ToList();
  
                      if (nonMeasurableFields != null &amp;&amp; nonMeasurableFields.Count &gt; 0)
                      {
                          #region Outer For Loop
  
                          for (int index = 0; index &lt; processedData.Count; index++)
                          {
                              var baseDict = processedData.ElementAt(index);
  
                              Dictionary&lt;String, Object&gt; compareDict = null;
  
                              #region Recursive Loop
  
                              for (int recursiveIndex = index + 1; recursiveIndex &lt; processedData.Count; recursiveIndex++)
                              {
                                  compareDict = processedData.ElementAt(recursiveIndex);
  
                                  int matchesCount = 0;
  
                                  #region comparison logic
  
                                  foreach (var key in nonMeasurableFields)
                                  {
                                      var baseDictValue = baseDict[key];
                                      var compareDictValue = compareDict[key];
  
                                      if (baseDictValue == null &amp;&amp; compareDictValue == null)
                                      {
                                          matchesCount++;
                                      }
                                      else
                                      {
                                          if (baseDictValue != null &amp;&amp; compareDictValue == null)
                                          {
                                              matchesCount = 0;
                                          }
                                          else if (baseDictValue == null &amp;&amp; compareDictValue != null)
                                          {
                                              matchesCount = 0;
                                          }
                                          else if (baseDictValue != null &amp;&amp; compareDictValue != null)
                                          {
                                              if (baseDictValue.Equals(compareDictValue))
                                              {
                                                  matchesCount++;
                                              }
                                              else
                                              {
                                                  matchesCount = 0;
                                              }
                                          }
  
                                      }
                                  }
  
                                  #endregion
  
                                  #region If Match -- Combine
  
                                  if (matchesCount == nonMeasurableFields.Count)
                                  {
                                      #region combine logic
  
                                      // Combine the two dictionary .. 
  
                                      processedData.Remove(baseDict);
                                      processedData.Remove(compareDict);
  
                                      // combine the base and compare dict
  
                                      Dictionary&lt;String, Object&gt; combinedDict = new Dictionary&lt;string, object&gt;();
  
                                      var keyNeededInDict = baseDict.Keys.ToList();
  
                                      foreach (var key in keyNeededInDict.ToList())
                                      {
                                          if (nonMeasurableFields.Contains(key))
                                          {
                                              combinedDict.Add(key, baseDict[key]);
                                          }
                                          else
                                          {
                                              Object value = Convert.ToDouble(baseDict[key]) + Convert.ToDouble(compareDict[key]);
  
                                              combinedDict.Add(key, value);
                                          }
                                      }
  
                                      processedData.Add(combinedDict);
  
                                      index = -1; // Resetting the looping index so that the merging works for all values
                                      recursiveIndex = -1; // Ensuring all the values are considered at least once whenever 
                                      // a change is made to the list (i.e merging the dict)
                                      break;
                                      #endregion
                                  }
                                  else
                                  {
                                      // No matches
                                      // continue to next
                                  }
  
                                  #endregion
                              }
  
                              #endregion
                          }
  
                          #endregion
                      }
  </code></pre>
  
  <p><strong>NOTE :</strong> <em>I will have information of which key(Value for the key) are of string type and Numeric type.
  The sample provided is for demonstration purpose only.The keys and values will be only known at the run time.
  I am supposed to combine the two dictionaries if the string values are equal.I will add the numeric values while combining it.</em> </p>
  
  <p><strong>Edit 2 :</strong> 
  All Dictionaries in the list will have same keys
  No values will be discarded.Dictionaries with same values will be combined.</p>