Saltar al contenido

usando LINQ para encontrar la suma acumulada de un array de números en C#

Sé libre de divulgar nuestro espacio y códigos en tus redes sociales, ayúdanos a hacer crecer nuestra comunidad.

Solución:

Hay un tiempo para la generalidad y hay un tiempo para resolver el problema realmente planteado. Este es uno de los últimos tiempos. Si desea crear un método que convierta una secuencia de dobles en una secuencia de sumas parciales, simplemente hágalo:

public static IEnumerable CumulativeSum(this IEnumerable sequence)

    double sum = 0;
    foreach(var item in sequence)
    
        sum += item;
        yield return sum;
            

Fácil. Sin perder el tiempo con agregados y consultas complicadas y demás. Fácil de entender, fácil de depurar, fácil de usar:

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

Ahora, observo que si esa es la entrada del usuario, entonces double. Parse puede generar una excepción; podría ser una mejor idea hacer algo como:

public static double? MyParseDouble(this string s)

    double d;
    if (double.TryParse(s, out d))
        return d;
    return null;


public static IEnumerable CumulativeSum(this IEnumerable 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();

y ahora no obtiene una excepción si el usuario comete un error de escritura; obtienes valores nulos.

Tuve un requerimiento similar hace algún tiempo. Básicamente, necesitaba hacer una agregación, pero también necesitaba seleccionar cada valor intermedio. Así que escribí un método de extensión llamado SelectAggregate (probablemente no sea el nombre más apropiado, pero no pude encontrar nada mejor entonces) que se puede usar así:

double[] numbers = new []  0.3, 0.4, 0.3 ;
double[] cumulativeSums = numbers.SelectAggregate(0.0, (acc, x) => acc + x).ToArray();

Aquí está el código:

    public static IEnumerable SelectAggregate(
        this IEnumerable source,
        TAccumulate seed,
        Func func)
    
        source.CheckArgumentNull("source");
        func.CheckArgumentNull("func");
        return source.SelectAggregateIterator(seed, func);
    

    private static IEnumerable SelectAggregateIterator(
        this IEnumerable source,
        TAccumulate seed,
        Func func)
    
        TAccumulate previous = seed;
        foreach (var item in source)
        
            TAccumulate result = func(previous, item);
            previous = result;
            yield return result;
        
    

Quieres usar el Aggregate operador, con List como acumulador de agregación. De esa manera puedes producir una proyección que es en sí misma una secuencia de sumas.

He aquí un ejemplo para empezar:

double[] runningTotal = textBox_f.Text
            .Split(new char[]',')
            .Select(s => double.Parse(s))
            .Aggregate((IEnumerable)new List(), 
                       (a,i) => a.Concat(new[]a.LastOrDefault() + i))
            .ToArray();

Calificaciones y reseñas

Finalizando este artículo puedes encontrar las críticas de otros programadores, tú aún tienes la opción de insertar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *