c# - Merge N amount of DataTables while summing one of the columns -


i have n amount of datatables, need merge them 1 datatable, while summing "value" column tables have. example below.

enter image description here

please note: can amount of tables merged, fields dynamic meaning not necessary "year" there, can "value" column there, , tables have same columns.

my quick&dirty solution this...

public class program {     static void main()     {         //make dummy data         list<datatable> dts = new list<datatable>();          random rnd = new random();         (int = 0; < 20; i++)         {             var dt = new datatable();              dt.columns.add("foo", typeof(int));             dt.columns.add("bar", typeof(int));             dt.columns.add("baz", typeof(int));             dt.columns.add("value", typeof(int));              (int j = 0; j < 1000; j++)             {                 dt.rows.add(rnd.next(1, 5), rnd.next(1, 5), rnd.next(1, 5), rnd.next(1, 2000));             }             dts.add(dt);         }          //dummy data complete          // grouping step         var intermediateresult = dts.selectmany(x => x.rows.cast<datarow>()).groupby(x => x, new notvaluecolumncomparer()).select(x => new { grp = x.key, sum = x.sum(y => y.field<int>("value")) });           // transform data tabe         var result = new datatable();          foreach (var col in dts.first().columns.cast<datacolumn>())         {             result.columns.add(col.columnname);         }          foreach (var item in intermediateresult)         {             var row = result.newrow();              foreach (var grpfield in item.grp.table.columns.cast<datacolumn>().where(x => x.columnname != "value"))             {                 row[grpfield.columnname] = item.grp[grpfield.columnname];             }             row["value"] = item.sum;              result.rows.add(row);         }         //transform end      }      //the class trick     public class notvaluecolumncomparer : iequalitycomparer<datarow>     {         //compare columns value column         public bool equals(datarow x, datarow y)         {             foreach (var col in x.table.columns.cast<datacolumn>())             {                 if (col.columnname != "value")                     if (x[col.columnname] != y[col.columnname])                         return false;             }             return true;         }           //as simple hash code ... xor values hash codes         public int gethashcode(datarow obj)         {             int res = 0;             foreach (var col in obj.table.columns.cast<datacolumn>())             {                 if (col.columnname != "value")                     res ^= obj[col].gethashcode();             }             return res;         }     } } 

if not afraid of additional libraries, might want have ad dynamic linq ...


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -