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.
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
Post a Comment