开发者

Linq using Aggregate() for List

From the Data

OrderID     OrderAmt   OrderDate                                              
----------- ---------- --------------------
1           10.50      2003-10-11 08:00:00
2           11.50      2003-10-11 10:00:00
3           1.25       2003-10-11 12:00:00
4           100.57     2003-10-12 09:00:00
5           19.99      2003-10-12 11:00:00
6           47.14      2003-10-13 10:00:00
7           10.08      2003-10-13 12:00:00
8           7.50       2003-10-13 19:00:00
9           9.50       2003-10-13 21:00:00

I want to display the following running total

OrderId     OrderDate            OrderAmt   Running Total                        
----------- -------------------- ---------- ------------- 
1           2003-10-11 08:00:00  10.50      10.50
2           2003-10-11 10:00:00  11.50      22.00
3           2003-10-11 12:00:00  1.25       23.25
4           2003-10-12 09:00:00  100.57     123.82
5           2003-10-12 11:00:00  19.99      143.81
6           2003-10-13 10:00:00  47.14      190.9开发者_运维技巧5
7           2003-10-13 12:00:00  10.08      201.03
8           2003-10-13 19:00:00  7.50       208.53
9           2003-10-13 21:00:00  9.50       218.03

From the following list

List<OrderData> ord = new List<OrderData>();

ord.Add(new OrderData() { OrderNumber=1, OrderAmount=10.50, 
OrderDate=new DateTime(2003,10,11)});

ord.Add(new OrderData() { OrderNumber=2, OrderAmount=11.50,
OrderDate=new DateTime(2003,10,11)});

ord.Add(new OrderData() { OrderNumber=3, OrderAmount=1.25,
OrderDate=new DateTime(2003,10,11)});

ord.Add(new OrderData() { OrderNumber=4, OrderAmount=100.57,
OrderDate =new DateTime(2003,10,12)});

ord.Add(new OrderData() { OrderNumber=5, OrderAmount=19.99,
OrderDate=new DateTime(2003,10,12)});

ord.Add(new OrderData() { OrderNumber=6, OrderAmount=47.14,
OrderDate =new DateTime(2003,10,13)});

ord.Add(new OrderData() { OrderNumber=7, OrderAmount=10.08,
OrderDate=new DateTime(2003,10,13)});

ord.Add(new OrderData() { OrderNumber=8, OrderAmount=7.50,
OrderDate=new DateTime(2003,10,13)});

ord.Add(new OrderData() { OrderNumber=9, OrderAmount=9.50,
OrderDate=new DateTime(2003,10,13)});

How to reshape the following query

var query = from o in ord
            select new
            {
             OrdNumber=o.OrderNumber,
             OrdDate=o.OrderDate,
             Amount=o.OrderAmount,
            RunntingTotal =ord.Aggregate(0,(o a,o b)=>
           {a.OrderAmount+b.OrderAmount;}) 
            };


You can't do this using the built-in Aggregate method.

Darin's answer will give you what you need, but has side-effects (ie, the query updates the total variable as it enumerates).

If you want a "pure" query without side-effects then you'll need to create some sort of Accumulate extension method and use that instead of Aggregate:

var query = ord.Accumulate(
    new { Order = (OrderData)null, Total = 0.0 },
    (a, x) => new { Order = x, Total = a.Total + x.OrderAmount });

foreach (var x in query)
{
    Console.WriteLine("{0}\t{1}\t{2}\t{3}",
        x.Order.OrderNumber, x.Order.OrderDate, x.Order.OrderAmount, x.Total);
}

// ...

public static class EnumerableExtensions
{
    public static IEnumerable<TAccumulate> Accumulate<TSource, TAccumulate>(
        this IEnumerable<TSource> source,
        TAccumulate seed,
        Func<TAccumulate, TSource, TAccumulate> func)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        if (func == null)
            throw new ArgumentNullException("func");

        TAccumulate accumulator = seed;
        foreach (TSource item in source)
        {
            accumulator = func(accumulator, item);
            yield return accumulator;
        }
    }
}


double total = 0;
var result = 
    (from o in ord
     select new
     {
         OrdNumber = o.OrderNumber,
         OrdDate = o.OrderDate,
         Amount = o.OrderAmount,
         RunntingTotal = total += o.OrderAmount
     }).ToArray();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜