locked
Extension method, SumIf on generic List<T> RRS feed

  • 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".


    Sunday, March 18, 2012 12:31 AM
    Moderator

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".


    Sunday, March 18, 2012 12:31 AM
    Moderator