汇总值直到达到限制 [英] Aggregate values until a limit is reached

查看:68
本文介绍了汇总值直到达到限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要类似于AggregateWhile方法的东西.标准的System.Linq.Enumerable类不提供它.到目前为止,我一直能够利用标准的LINQ方法来解决我遇到的每个问题.因此,我想知道在这种情况下是否仍然可行,或者我是否真的需要使用非标准方法来扩展LINQ.

I need something similar to an AggregateWhile method. The standard System.Linq.Enumerable class doesn't provide it. Until now I've always been able to leverage the standard LINQ methods to solve every problem I've encountered. So I'd like to know if that's still possible in this case, or if I really do need to extend LINQ with a non-standard method.

假设的AggregateWhile方法将遍历序列并应用累加器.一旦谓词返回false,聚合将完成.结果是直到(不是)元素的集合,包括谓词失败的元素.

The hypothetical AggregateWhile method would iterate over a sequence and apply the accumulator. The aggregation would be complete once a predicate returns false. The result is the aggregration of elements up to but not including the element for which the predicate failed.

这是一个例子.我们有一个带有累加器的List { 1, 2, 3, 4, 5 },该累加器将两个输入数字相加,并且一个谓词指出累加必须小于12.AggregateWhile将返回10,因为这是1 + 2 + 3 + 4的结果.最后5个将使总数超过限制.在代码中:

Here's an example. We have a List { 1, 2, 3, 4, 5 } with an accumulator that adds the two input numbers together, and a predicate that states the accumulation must be less than 12. AggregateWhile would return 10 since that's the result of 1 + 2 + 3 + 4 and adding the final 5 would push the total over the limit. In code:

var list = new List<int> { 1, 2, 3, 4, 5 };
int total = list.AggregateWhile( (x, y) => x + y, a => a < 12 ); // returns 10

我需要一个纯粹的功能性解决方案,因此无法关闭临时变量.

I need a purely functional solution, so closing over a temporary variable is not an option.

推荐答案

您可以自己编写函数,也可以在累加器中携带一个标志:

You could either write the function yourself, or carry a flag with your accumulator:

int total = list.Aggregate(new { value = 0, valid = true }, 
                          (acc, v) => acc.value + v < 12 && acc.valid ?
                                      new { value = acc.value + v, valid = true } :
                                      new { value = acc.value, valid = false },
                            acc => acc.value); 

这很丑陋,所以写一个新的AggregateWhile会更好:

It's quite ugly, so writting a new AggregateWhile would be nicer:

public static TSource AggregateWhile<TSource>(this IEnumerable<TSource> source, 
                                         Func<TSource, TSource, TSource> func,
                                         Func<TSource, bool> predicate)
{
   using (IEnumerator<TSource> e = source.GetEnumerator()) {
       TSource result = e.Current;
       TSource tmp = default(TSource);
       while (e.MoveNext() && predicate(tmp = func(result, e.Current))) 
            result = tmp;
       return result;
   }
}

(为简洁起见,没有错误检查)

这篇关于汇总值直到达到限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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