获取列表中的所有项目,直到累积总和达到限制值

时间:2019-10-28 07:00:44

标签: c# aggregate-functions generic-list cumulative-sum

我有一个List<Tuple<DateTime, double>>。该列表保证按DateTime排序。现在,我要获取累积总和中包含的所有项目,直到达到极限值为止。最优雅的方法是什么?

DateTime             | double     | c. sum   | Limit | in result list?
-----------------------------------------------------------------------
2019-10-28 07:51:10  | 0.3        | 0.3      | 5     | yes
2019-10-28 07:51:11  | 0.2        | 0.5      | 5     | yes
2019-10-28 07:51:12  | 0.7        | 1.2      | 5     | yes
2019-10-28 07:51:13  | 0.67       | 1.87     | 5     | yes
2019-10-28 07:51:14  | 1.0        | 2.87     | 5     | yes
2019-10-28 07:51:15  | 0.1        | 2.97     | 5     | yes
2019-10-28 07:51:16  | 0.9        | 3.87     | 5     | yes
2019-10-28 07:51:17  | 0.32       | 4.19     | 5     | yes
2019-10-28 07:51:18  | 0.21       | 4.40     | 5     | yes
2019-10-28 07:51:19  | 0.25       | 4.65     | 5     | yes
2019-10-28 07:51:20  | 0.6        | 5.25     | 5     | yes (more values don't need to be calculated, limit is reached)
-----------------------------------------------------------------------
2019-10-28 07:51:21  | 0.4        | 5.65     | 5     | no

在此先感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

我认为TakeWhile在这里可能是个不错的候选人。

var list = new []{1,2,3,4};

var sum1 = 0;
var triggerValue = 6;
var afterSumReached = list.TakeWhile( x => { sum1 += x; return sum1 <= triggerValue; } );
// first 3 elements.

var sum2 = 0;
var beforeSumReached = list.TakeWhile( x => { 
    if( sum2 + x >= triggerValue) return false;
    sum2+=x; 
    return true;
});
// first 2 elements 

答案 1 :(得分:1)

我想我会做这样的事情:

var list = new List<Tuple<DateTime, double>>
{
    ....
};

var sum = 0d;
var limit = 10d;

var result = list.TakeWhile(x => (sum += x.Item2) < limit).ToList();

答案 2 :(得分:1)

您可以编写如下扩展方法:

public static class ListTupleExtension
{
    public static List<Tuple<DateTime, double>> CumulativeSum(this List<Tuple<DateTime, double>> sequence, double limit)
    {
        List<Tuple<DateTime, double>> result = new List<Tuple<DateTime, double>>();
        double sum = 0;
        foreach(var item in sequence)
        {
            if (sum <= limit)
            {
                sum += item.Item2;
            }

            result.Add(new Tuple<DateTime, double>(item.Item1, sum));
        }

        return result;
    }
}

然后在列表中将其称为

list = list.CumulativeSum(limit);

检查this dotnetfiddle,以演示用法。