Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

using LINQ to find the cumulative sum of an array of numbers in C#

I have a csv string containing doubles (e.g "0.3,0.4,0.3"), and I want to be able to output a double array containing the cumulative sum of these numbers (e.g [0.3,0.7,1.0]).

So far, I have

double[] probabilities = textBox_f.Text.Split(new char[]{','}).Select(s => double.Parse(s)).ToArray();

which gives the numbers as an array, but not the cumulative sum of the numbers.

Is there any way to continue this expression to get what I want, or do I need to use iteration to create a new array from the array I already have?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's a time for generality, and there's a time for solving the problem actually posed. This is one of the latter times. If you want to make a method that turns a sequence of doubles into a sequence of partial sums, then just do that:

public static IEnumerable<double> CumulativeSum(this IEnumerable<double> sequence)
{
    double sum = 0;
    foreach(var item in sequence)
    {
        sum += item;
        yield return sum;
    }        
}

Easy. No messing around with aggregates and complicated queries and whatnot. Easy to understand, easy to debug, easy to use:

textBox_f.Text
    .Split(new char[]{','})
    .Select(s => double.Parse(s))
    .CumulativeSum()
    .ToArray();

Now, I note that if that is user input then double.Parse can throw an exception; it might be a better idea to do something like:

public static double? MyParseDouble(this string s)
{
    double d;
    if (double.TryParse(s, out d))
        return d;
    return null;
}

public static IEnumerable<double?> CumulativeSum(this IEnumerable<double?> sequence)
{
    double? sum = 0;
    foreach(var item in sequence)
    {
        sum += item;
        yield return sum;
    }        
}
...
textBox_f.Text
    .Split(new char[]{','})
    .Select(s => s.MyParseDouble())
    .CumulativeSum()
    .ToArray();

and now you don't get an exception if the user makes a typing mistake; you get nulls.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...