代码之家  ›  专栏  ›  技术社区  ›  user215675

对列表使用aggregate()的linq

  •  1
  • user215675  · 技术社区  · 15 年前

    从数据

    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
    

    我想显示以下运行总数

    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.95
    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
    

    从以下列表中

    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)});
    

    如何重塑以下查询

    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;}) 
                };
    
    2 回复  |  直到 14 年前
        1
  •  5
  •   Community leo1    7 年前

    你不能用内置的 Aggregate 方法。

    Darin's answer 将为您提供所需的,但有副作用(即,查询更新 total 变量)。

    如果您想要一个没有副作用的“纯”查询,那么您需要创建一些 Accumulate 扩展方法并使用它代替 骨料 :

    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;
            }
        }
    }
    
        2
  •  2
  •   Darin Dimitrov    15 年前
    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();