c# - Linq Exclude columns in children -


i trying following: given list of dynamic objects perform group using list of columns provided. here's have far:

using newtonsoft.json;  private static void main(string[] args) {     dynamic[] data = {         new { = "a1", b = "b1", c = "c1", d = "d1", e = "e1", f = "f1"},         new { = "a1", b = "b1", c = "c1", d = "d1", e = "e1", f = "f1", g = "g1"},         new { = "a1", b = "b1", c = "c1", d = "d1", e = "e1", h = "h1", = "i1"}     };      var newlist = data.groupby(row => new { row.a, row.b, row.c, row.d, row.e })         .select(             y =>                 new                 {                     = y.key.a, b = y.key.b, c = y.key.c, d = y.key.d, e = y.key.e,                     children = y.tolist()                 });      var str = jsonconvert.serializeobject(newlist);      console.read(); } 

this works per needs. however, want rid of additional columns appear part of children field. here's output getting str:

[    {       "a":"a1",       "b":"b1",       "c":"c1",       "d":"d1",       "e":"e1",       "children":[          {             "a":"a1",             "b":"b1",             "c":"c1",             "d":"d1",             "e":"e1",             "f":"f1"          },          {             "a":"a1",             "b":"b1",             "c":"c1",             "d":"d1",             "e":"e1",             "f":"f1",             "g":"g1"          },          {             "a":"a1",             "b":"b1",             "c":"c1",             "d":"d1",             "e":"e1",             "h":"h1",             "i":"i1"          }       ]    } ] 

what ideally want following:

[    {       "a":"a1",       "b":"b1",       "c":"c1",       "d":"d1",       "e":"e1",       "children":[          {             "e":"e1",             "f":"f1"          },          {             "f":"f1",             "g":"g1"          },          {             "h":"h1",             "i":"i1"          }       ]    } ] 

any suggestions on how can achieved? know there can number of fields common across objects (e.g., a,b,c,d,e) have no control on others (e.g., f, g, h etc.)

you can use expandoobject class store properties unique each item , reflection select unique properties.

here's why managed scratch in linqpad:

dynamic[] data = {     new { = "a1", b = "b1", c = "c1", d = "d1", e = "e1", f = "f1" },     new { = "a1", b = "b1", c = "c1", d = "d1", e = "e1", f = "f1", g = "g1" },     new { = "a1", b = "b1", c = "c1", d = "d1", e = "e1", h = "h1", = "i1" } };  var keyproperties = new[] { "a", "b", "c", "d", "e" }; var newlist = data.groupby(row => new { row.a, row.b, row.c, row.d, row.e }).select(     y => new          {              = y.key.a,              b = y.key.b,              c = y.key.c,              d = y.key.d,              e = y.key.e,              children = y.select(                  item =>                  {                      ienumerable<dynamic> itemprops = item.gettype().getproperties();                      list<dynamic> properties =                          itemprops.where(p => !enumerable.contains(keyproperties, p.name)).tolist();                      var result = new expandoobject();                      foreach (var property in properties)                      {                          var value = property.getvalue(item, null);                          if (value != null)                          {                              ((idictionary<string, object>)result).add(property.name, value);                          }                      }                      return result;                  }).tolist()          }); var str = jsonconvert.serializeobject(newlist); 

and result is:

[   {     "a": "a1",     "b": "b1",     "c": "c1",     "d": "d1",     "e": "e1",     "children": [       {         "f": "f1"       },       {         "f": "f1",         "g": "g1"       },       {         "h": "h1",         "i": "i1"       }     ]   } ] 

edit

to merge elements @ child level need change projection bit.

first of all, select becomes selectmany return collection of keyvaluepair<string, object> subsequently grouped name , concatenated array:

children = y.selectmany(item => {     ienumerable<dynamic> itemprops = item.gettype().getproperties();     list<dynamic> properties = itemprops.where(p => !enumerable.contains(keyproperties,p.name)).tolist();     var result = new expandoobject();     foreach(var property in properties)     {         var value = property.getvalue(item, null);         if(value != null)             ((idictionary<string, object>)result).add(property.name, value);     }     return (idictionary<string, object>)result; }).groupby(prop => prop.key, prop => prop.value) .select(g =>  {     var result = new expandoobject();     ((idictionary<string, object>)result).add(g.key, g.toarray());     return result; }) .tolist() 

it's not elegant code should work.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -