score:7
the next cell val required is a calculated one based on all the totalpurchases values for a given monthyr. so i need to compute a "percentage of the total" value for all itemsformonthyear "records" with the same monthyr value.
well, first, you need to get the ones with the same monthyr
:
var allmonthyr = itemsformonthyearlist.where(x => x.monthyr == ifmy.monthyr);
then it's a simple sum
:
var totalpurchasesofmonthyr = allmonthyr.sum(x => x.totalpurchases);
var percentoftotal = ifmy.totalpurchases / totalpurchasesofmonthyr;
now, that turns out to be horribly inefficient - as you're iterating this list a bunch of times unnecessarily. much better to group and then sum once:
var groupeditemsformonthyr = itemsformonthyearlist.tolookup(x => x.monthyr);
var totalsformonthyr = groupeditemsformonthyr.todictionary(
x => x.key,
x => x.sum(x => x.totalpurchases)
);
var percentoftotal = ifmy.totalpurchases / totalsformonthyr[ifmy.monthyr];
score:0
this code, from mark brackett's self-proclaimed "horribly inefficient" first take, works just fine:
private string getpercentforpurchaseformonthyearasstr(decimal totpurchasesforitemmonthyear, string monthtocalculate)
{
var allrecordsformonthyr = itemsformonthyearlist.where(x => x.monthyr == monthtocalculate);
var totalpurchasesofmonthyr = allrecordsformonthyr.sum(x => x.totalpurchases);
var percentoftotal = totpurchasesforitemmonthyear / totalpurchasesofmonthyr;
return percentoftotal.tostring("p", cultureinfo.currentculture);
}
since the grouped code wouldn't compile for me, i'm happy with the code above.
score:1
decimal alltotalpurchases = itemsformonthyearlist.where(s => s.monthyr.equals("apr 14")).select(s => s.totalpurchases).sum();
score:2
this is mark brackett's answer with what i believe are the appropriate fixes:
// this is code that goes outside your loop
var groupeditemsformonthyr=itemsformonthyearlist.groupby(x=>x.monthyr);
var totalsformonthyr=groupeditemsformonthyr.todictionary(
x => x.key,
x => x.sum(y => y.totalpurchases)
);
// this is the code that goes inside your loop
var percentoftotal = ifmy.totalpurchases / totalsformonthyr[ifmy.monthyr];
here is my answer given a list<itemsformonthyear>
and returns a list<itemsformonthyear>
in items with the percentoftotal correctly filled out:
var items=itemsformonthyearlist.groupby(x=>x.monthyr)
.select(x=>new { total=x.sum(y=>y.totalpurchases), i=x })
.select(x=>x.i.select(y=>new itemsformonthyear {
itemdescription=y.itemdescription,
monthyr=y.monthyr,
totalpackages=y.totalpackages,
totalpurchases=y.totalpurchases,
averageprice=y.averageprice,
percentoftotal=(double)y.totalpurchases/(double)x.total
}))
.selectmany(x=>x);
here's my test code:
void main()
{
var itemsformonthyearlist=new[]{
new itemsformonthyear { itemdescription="a",monthyr="aug 2014",totalpackages=1,totalpurchases=1,averageprice=1},
new itemsformonthyear { itemdescription="a",monthyr="sep 2014",totalpackages=1,totalpurchases=1,averageprice=1},
new itemsformonthyear { itemdescription="a",monthyr="sep 2014",totalpackages=1,totalpurchases=1,averageprice=1},
new itemsformonthyear { itemdescription="a",monthyr="oct 2014",totalpackages=1,totalpurchases=1,averageprice=1},
new itemsformonthyear { itemdescription="a",monthyr="oct 2014",totalpackages=1,totalpurchases=1,averageprice=1},
new itemsformonthyear { itemdescription="a",monthyr="oct 2014",totalpackages=1,totalpurchases=1,averageprice=1},
};
var items=itemsformonthyearlist.groupby(x=>x.monthyr)
.select(x=>new { total=x.sum(y=>y.totalpurchases), i=x })
.select(x=>x.i.select(y=>new itemsformonthyear {
itemdescription=y.itemdescription,
monthyr=y.monthyr,
totalpackages=y.totalpackages,
totalpurchases=y.totalpurchases,
averageprice=y.averageprice,
percentoftotal=(double)y.totalpurchases/(double)x.total
}))
.selectmany(x=>x);
items.dump();
}
public class itemsformonthyear
{
public string itemdescription { get; set; }
public string monthyr { get; set; }
public int totalpackages { get; set; }
public decimal totalpurchases { get; set; }
public decimal averageprice { get; set; }
public double percentoftotal { get; set; }
}
score:3
you can do this to calculate the amount of total purchases on a month:
decimal totalpurchases = itemsformonthyearlist.where(item => item.monthyr == "apr 14")
.sum(item => item.totalpurchases);
you can then calculate the percentage of a given item by doing:
decimal percentage = (itemsformonthyearlist.single(item => item.itemdescription == "cocoa puffs")
.totalpurchases / totalpurchases) * 100;
Source: stackoverflow.com
Related Query
- How can I sum values across a generic list using LINQ?
- How should i use group by and sum on different values of list of models using linq
- How to select values within a provided index range from a List using LINQ
- Convert a list to a dictionary and sum up values using linq
- How can I write the following code more elegantly using LINQ query syntax?
- How can I code an outer join using LINQ and EF6?
- How to add list of missing values in c# list using Linq
- How can I sort a list of numerical strings? Preferably using LINQ
- how can i page into my list using linq
- C# how can I sort a list of file by index using linq
- How to get sum of data in a list using multiple column values
- How can I select using LINQ for an entry that contains a LIST with more than one row?
- How to check if two values exist in a list using linq in c#
- how can get List of users in active directory using LINQ to LDAP?
- How can I get a comma separated list of values from a List using LINQ?
- How can I filter a list using generics and Linq extension methods?
- How can I split a list with embedded transition markers using LINQ or Reactive Extensions?
- How can I simultaneously group and sum a list of items using Linq?
- How can I obtain objects from list with C# LINQ using boolean conditions?
- How can I check the number of calls to the database in LINQ query when using .NET Core and Code First?
- Formatting a string using values from a generic list by LINQ
- How can I get the next appropriate value from a generic list using LINQ?
- How to retrieve the values from list using indexes by linq query?
- Using Linq to object, how can I get one field's value based on another in the same list
- How to Group and Sum List of Lists using Linq
- How to sum values for multiple columns in DataTable using Groupby with Linq
- How can I return a object with the sum of all objects from a list using Linq?
- I need to find max total of the sum of integers in Generic list using Linq
- using Linq to sort a list based on the sum of values in each item
- Using LINQ and EF, how to remove values from database where not in list of items
More Query from same tag
- Read from xml file to objectlist using Linq
- Get latest record from a grouping and filter on status
- How to work inline with custom IEqualityComparer<T> parameters
- Where is the source for System.Linq.Enumerable.ToList()?
- How do I group by using anonymous type
- .Select not updatingObservableCollection of view model objects
- Optimisation of LinqToXml
- VB.NET and LINQ - Group by in a DataTable
- Sort list of DateTime values in descending order including time
- Do any items in List<string> contain part of a separate string
- Entity Framework 4.1 Link table query how to?
- EntityFramework using linq is slow
- Greek characters get corrupted when returned as part of XML element in SQL Server
- Finding Max Question
- Get distinct columns with order by date
- How to select all items in a radious in xyz space?
- Take objects which attributes contains any element of array
- Check if two dates completely overlaps a date range
- C# Linq multi OR
- Linq with data Error condition ( 'Date' is not supported in LINQ)
- Linq to entity - Call user defined method from query
- Conversion of SQL into LINQ
- Filtering include items in LINQ and Entity Framework
- Getting DataTable column names using linq, error when column is null
- Restrict EF query to a base type with TPT inheritance
- Linq - multiple rows as string
- linq-to-sql: GROUP BY and MIN() in SELECT part
- List of Days irrespective of time
- Elegant way to add a specific character after each char in a string
- conditional where