Answered by:
Extension method, SumIf on generic List<T>

Question
-
I need to write a generic extension method for List<T> that conditionally considers each string property of T, then sums a cooresponding decimal property of T if a condition is met. My effort thus far:
// pseudo: foreach(p in Persons) { if(p.Name == "mort"){sum p.Amount;} }
public static double SumIf<T>(this List<T> ListItems, string targetString, ?strValues?, ?dblValues?)
{
double sum = 0;
foreach(T item in ListItems)
{
if(item.?strValue? == targetString){ sum += item.?dblValue? ; }
}
return sum;
}Thanks for any guidance
Mort
Saturday, March 17, 2012 11:12 PM
Answers
-
A generic "SumIf" would probably take a predicate, and look something like:
public static double SumIf(this IEnumerable<T> collection, Func<T, bool> predicate, Func<T, double> valueFunc) { double total = 0.0; foreach(var item in collection) { if (predicate(item)) total += valueFunc(item); } return total; }
This would then allow you to write something like:
double total = someCollection.SumIf(item => item.Name == "mort", item => item.Amount);
This works by passing two delegates (instead of one, like many LINQ methods) - the first defines the "if condition" via a predicate, the second tells the method how to extract a double value to sum.
Reed Copsey, Jr. - http://reedcopsey.com
If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".- Edited by Reed Copsey, JrMVP, Moderator Sunday, March 18, 2012 12:32 AM
- Proposed as answer by servy42 Monday, March 19, 2012 3:00 PM
- Marked as answer by Neddy Ren Wednesday, March 28, 2012 5:57 AM
Sunday, March 18, 2012 12:31 AMModerator
All replies
-
You can already .Aggregate a collection using LINQ. That does the sum=0, and sum += foo parts. The foo part can be a lambda expression to select the value of foo.
I think your extension method generic function will need to be qualified with a where expression, something that allows you to specify the class that has the .strValue and .dblValue properties.
Show the rest of the syntax that you want to use:
myList.SumIf( "mort", ..., ... );
show what you hope to be able to put where the ...'s are.
Sunday, March 18, 2012 12:11 AM -
A generic "SumIf" would probably take a predicate, and look something like:
public static double SumIf(this IEnumerable<T> collection, Func<T, bool> predicate, Func<T, double> valueFunc) { double total = 0.0; foreach(var item in collection) { if (predicate(item)) total += valueFunc(item); } return total; }
This would then allow you to write something like:
double total = someCollection.SumIf(item => item.Name == "mort", item => item.Amount);
This works by passing two delegates (instead of one, like many LINQ methods) - the first defines the "if condition" via a predicate, the second tells the method how to extract a double value to sum.
Reed Copsey, Jr. - http://reedcopsey.com
If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".- Edited by Reed Copsey, JrMVP, Moderator Sunday, March 18, 2012 12:32 AM
- Proposed as answer by servy42 Monday, March 19, 2012 3:00 PM
- Marked as answer by Neddy Ren Wednesday, March 28, 2012 5:57 AM
Sunday, March 18, 2012 12:31 AMModerator