C# - 聚合中的终止()

时间:2009-12-03 11:51:37

标签: c# extension-methods

来自以下模拟

int[] amountWithdrawal = { 10, 20, 30, 140, 50, 70 };

amountWithdrawal.Aggregate(100, (balance, withdrawal) => 
{
  Console.WriteLine("balance :{0},Withdrawal:{1}", balance, withdrawal);
 if (balance >= withdrawal)
 {
   return balance - withdrawal;
 }
 else return balance;
 }
);

我想终止聚合when the balance is less than the withdrawal。但我的代码遍历整个数组。如何终止它?

4 个答案:

答案 0 :(得分:5)

在我看来,你想要一个Accumulate方法,它产生一个新的累积值序列,而不是标量。像这样:

public static IEnumerable<TAccumulate> SequenceAggregate<TSource, TAccumulate>(
    this IEnumerable<TSource> source,
    TAccumulate seed,
    Func<TAccumulate, TSource, TAccumulate> func)
{
    TAccumulate current = seed;
    foreach (TSource item in source)
    {
        current = func(current, item);
        yield return current;
    }
}

然后你可以申请TakeWhile

int[] amountWithdrawal = { 10, 20, 30, 140, 50, 70 };

var query = amountWithdrawal.SequenceAggregate(100, (balance, withdrawal) => 
{
  Console.WriteLine("balance :{0},Withdrawal:{1}", balance, withdrawal);
  return balance - withdrawal;
}).TakeWhile (balance => balance >= 0);

我可以发誓在正常的LINQ to Objects中有类似的东西,但我现在找不到它......

答案 1 :(得分:1)

您应该照常使用Aggregate,然后使用Where省略负余额。

BTW,在LINQ方法中使用带副作用的函数(例如Console.WriteLine)是不好的做法。你最好先做所有的LINQ聚合和过滤,然后写一个foreach循环打印到控制台。

答案 2 :(得分:1)

用for循环替换聚合。

答案 3 :(得分:0)

您可能希望使用TakeWhile().Aggregate()并检查take while谓词中的余额。