Pregunta

Tengo un bucle como el siguiente, yo puedo hacer lo mismo usando SUMA múltiple?

foreach (var detail in ArticleLedgerEntries.Where(pd => pd.LedgerEntryType == LedgerEntryTypeTypes.Unload &&
                                                                pd.InventoryType == InventoryTypes.Finished))
{
     weight += detail.GrossWeight;
     length += detail.Length;
     items  += detail.NrDistaff;
}
¿Fue útil?

Solución

En términos técnicos, lo que tienes es probablemente la forma más eficiente de hacer lo que están pidiendo. Sin embargo, se podría crear un método de extensión en IEnumerable Cada llamada que podría hacerlo más sencillo:

public static class EnumerableExtensions
{
    public static void Each<T>(this IEnumerable<T> col, Action<T> itemWorker)
    {
        foreach (var item in col)
        {
            itemWorker(item);
        }
    }
}

Y llamarlo de esta manera:

// Declare variables in parent scope
double weight;
double length;
int items;

ArticleLedgerEntries
    .Where(
        pd => 
           pd.LedgerEntryType == LedgerEntryTypeTypes.Unload &&
           pd.InventoryType == InventoryTypes.Finished
    )
    .Each(
        pd => 
        {
            // Close around variables defined in parent scope
            weight += pd.GrossWeight; 
            lenght += pd.Length;
            items += pd.NrDistaff;
        }
    );

ACTUALIZACIÓN: Sólo una nota adicional. El ejemplo anterior se basa en un cierre. Las variables peso, longitud y artículos debe ser declarado en un ámbito primario, lo que les permite persisten después de cada llamada a la acción itemWorker. He actualizado el ejemplo para reflejar esto para una mayor claridad.

Otros consejos

Puede llamar Sum tres veces, pero será más lento, ya que hará tres bucles.

Por ejemplo:

var list = ArticleLedgerEntries.Where(pd => pd.LedgerEntryType == LedgerEntryTypeTypes.Unload
                                   && pd.InventoryType == InventoryTypes.Finished))

var totalWeight = list.Sum(pd => pd.GrossWeight);
var totalLength = list.Sum(pd => pd.Length);
var items = list.Sum(pd => pd.NrDistaff); 

Debido a la ejecución retardada, sino que también reevaluar la llamada Where cada vez, aunque eso no es un problema tal en su caso. Esto podría evitarse llamando ToArray, pero que hará que una asignación matriz. (Y no por ello deja correr tres bucles)

Sin embargo, a menos que tenga un gran número de entradas o está ejecutando el código en un bucle estrecho, que no tenga que preocuparse por el rendimiento.


Editar : Si realmente desea utilizar LINQ, se podría hacer mal uso Aggregate, como esto:

int totalWeight, totalLength, items;

list.Aggregate((a, b) => { 
    weight += detail.GrossWeight;
    length += detail.Length;
    items  += detail.NrDistaff;
    return a;
});

Este es el código fenomenalmente feo, pero debe realizar casi tan bien como un bucle recta.

También se puede resumir en el acumulador, (ver ejemplo a continuación), pero esto sería asignar un objeto temporal para cada elemento de la lista, que es una idea tonta. (Los tipos anónimos son inmutables)

var totals = list.Aggregate(
    new { Weight = 0, Length = 0, Items = 0},
    (t, pd) => new { 
        Weight = t.Weight + pd.GrossWeight,
        Length = t.Length + pd.Length,
        Items = t.Items + pd.NrDistaff
    }
);

también podría agrupar por cierto - 1 (que en realidad está incluido cualquiera de los artículos y luego tener que contar o summered):

 var results = from x in ArticleLedgerEntries
                       group x by 1
                       into aggregatedTable
                       select new
                                  {
                                      SumOfWeight = aggregatedTable.Sum(y => y.weight),
                                      SumOfLength = aggregatedTable.Sum(y => y.Length),
                                      SumOfNrDistaff = aggregatedTable.Sum(y => y.NrDistaff)
                                  };

En lo que a Tiempo de funcionamiento, es casi tan bueno como el bucle (con una adición constante).

Usted sería capaz de hacer esto al estilo de pivote, usando la respuesta en este tema: ¿es posible hacer pivotar datos utilizando LINQ?

Ok. Me doy cuenta de que no hay una manera fácil de hacer esto utilizando LINQ. Voy a tomar pueden foreach bucle porque entendía que no es tan malo. Gracias a todos ustedes

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top