扩展方法,在通用List< T>上的SumIf. [英] Extension method, SumIf on generic List<T>

查看:55
本文介绍了扩展方法,在通用List< T>上的SumIf.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为List(T)写一个通用的扩展方法,该方法有条件地考虑T的每个字符串属性,然后在满足条件的情况下求和T的相应十进制属性.到目前为止,我的努力:

I need to write an generic extension method for List(T) that conditionally considers each string property of T, then sums a corresponding decimal property of T if a condition is met. My effort thus far:

// foreach(p in Persons) { if(p.Name == "mort"){sum p.Amount;} }

public static double SumIf<T>(this T o, List<T> ListItems, 
          string targetStr, ?strVals?, ?dblVals?)
{
    double sum = 0;
    foreach(T item in ListItems)
    {
        if(item.?strVal? == targetStr){ sum += item.?dblVal? ; }
    }
    return sum;
}

感谢您的指导, 凡人

推荐答案

听起来您想要一种提取string属性和double属性的方法(假设您帖子中的十进制"是拼写错误,而不是"double" ")-Func在此处合适:

It sounds like you want a way of extracting the string property and double property (assuming that the "decimal" in your post was a typo rather than the "double" in your code) - Func is appropriate here:

public static double SumIf<T>(this IEnumerable<T> source, 
          string targetText,
          Func<T, string> textSelector,
          Func<T, double> valueSelector)
{
    double sum = 0;
    foreach (T item in source)
    {
        if (textSelector(item) == targetText)
        {
            sum += valueSelector(item);
        }
    }
    return sum;
}

(请注意,我已经删除了未使用的初始参数,并使其成为列表本身的扩展方法.对我来说,不使用该值似乎有点难闻……我还更改了参数类型到IEnumerable<T>,因为您实际上不需要将其作为列表.)

(Note that I've removed the unused initial parameter, and made it an extension method on the list itself. Not using the value feels like a bit of a smell to me... I've also changed the parameter type to IEnumerable<T> as you don't need it to be a list really.)

请注意,这实际上等效于:

Note that this actually mostly equivalent to:

public static double SumIf<T>(this IEnumerable<T> source, 
          string targetText,
          Func<T, string> textSelector,
          Func<T, double> valueSelector)
{
    return source.Where(x => textSelector(x) == targetText)
                 .Sum(valueSelector);
}

我个人可能会使用通用谓词函数,而不是字符串和文本选择器:

I'd personally probably go for a general predicate function instead of a string and a text selector:

public static double SumIf<T>(this IEnumerable<T> source, 
          Func<T, bool> predicate,
          Func<T, double> valueSelector)
{
    return source.Where(predicate)
                 .Sum(valueSelector);
}

那你会用

double sum = list.SumIf(x => x.Name == "mort", x => x.Amount);

...对我来说似乎和:

... which seems just as good to me as:

double sum = list.SumIf("mort", x => x.Name, x => x.Amount);

...但更加灵活.

如评论中所述,您真的需要吗?您是否在足够的地方使用它以使简单的位置/总和"呼叫难以忍受?哎呀,您可以使用条件运算符将其转换为Sum调用:

As noted in comments, do you really need this at all? Are you using it in sufficient places to make the simple Where/Sum calls unbearable? Heck, you can turn it into just a Sum call using the conditional operator:

double sum = list.Sum(x => x.Name == "mort" ? x => x.Amount : 0d);

这篇关于扩展方法,在通用List&lt; T&gt;上的SumIf.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆