c# - Best way to use LINQ to fill in gaps in my data -
yesterday posted question below on how use linq transform object several levels using 'group' flat structure:
linq groupby on object several levels
this kindly answered cédric bignon. reason wanted transformation populate componentart's silverlight xychart component userdata variable. however, i've found out there known bug component when displaying in stacked bar format. if there's gaps in data not display properly, need ensure users have value distinct values of category. in original question, i've put i'd userdata populated with, i'd need ensure [user = "bob", category = "international", spend = 0.00] present in results.
i've achieved using following code after linq statement have given me:
// linq statement provided @cedric var userdata = spend in allspend userdatapoint in (from monthspend in spend.spend spenddetail in monthspend.detail group spenddetail spenddetail.description g select new userdatapoint { user = spend.username, category = g.key, spend = g.sum(t => t.amount) }) select userdatapoint; // end list<userdatapoint> userdatanogaps = new list<userdatapoint>(); userdatanogaps = userdata.tolist(); foreach (string strcategory in userdata.select(c => c.category).distinct()) { var existing = userdata.where(c => c.category == strcategory).select(c => c.user); userdatanogaps.addrange(userdata.where(c => !existing.contains(c.user)).select(c => new userdatapoint() { user = c.user, category = strcategory, spend = 0 })); }
but code pretty slow when have on 1000 users , few categories. can somehow incorporated linq statement cédric provided or better off filling in gaps afterwards using code above?
you can prepare list of points users/categories 0
values merge userdata union
.
var userdatalist = userdata.tolist(); var userslist = userdatalist.select(x => x.uder).distinct().tolist(); var categorieslist = userdatalist.select(x => x.category).distinct().tolist(); // make list of userdatapoint 0 sums var empty = (from user in users category in categorieslist select new userdatapoint { user = user, category = category, spend = 0 }).tolist(); var merged = userdatalist.union(empty) .groupby(x => new { x.user, x.category }) // here sum empty points real .select(new userdatapoint { user = group.key.user, category = group.key.category, spend = group.sum(y => y.spend) }).tolist();
Comments
Post a Comment