如何计算积分呢?

本文关键字:计算 何计算 | 更新日期: 2023-09-27 18:01:27

如何从返回一系列(时间|值)对的Linq表达式构建一个"积分"函数?

。我的Linq表达式的结果是(日期|数量)对的列表:

var quantities = db.Stocks.Find(id).Trades.Select(
    x => new
    {
        date = x.Price.Date.Subtract(unix).TotalMilliseconds,
        value = x.Quantity
    }).ToList();

获得一系列(date | 累计数量)的有效方法是什么,其中每个记录都有截至该点的所有数量加上当前数量的总和?

EDIT1 -使它具体化:上面的查询返回可以是

  • 0:(01.01.2012 | 10)
  • 1:(01.1.2013 | -5)
  • 2:(01.01.2014 | 7)

我要找的是在每个离散的时间点有累积值:

  • 0:(01.01.2012 | 10)
  • 1:(01.01.2013 | 5)
  • 2:(01.01.2014 | 12)

EDIT2 -一种解决方案可能是"手动"组装结果,并将每个数量链接到其前一个数量:

var cumulatedQuantities = new List<Tuple<double, double>>();
cumulatedQuantities.Add(new Tuple<double, double>(quantities[0].date, quantities[0].value));
for (var i = 1; i <= quantities.Count - 1; i++ )
{
    cumulatedQuantities.Add(new Tuple<double, double>(quantities[i].date, quantities[i].value + cumulatedQuantities[i-1].Item2));
}

不知何故,感觉很丑…

如何计算积分呢?

按日期分组,然后将每组的数量加起来:

var quantities
    = db.Stocks.Find(id).Trades
               .GroupBy(x => x.Price.Date)
               .Select(x => new
                            {
                                date = x.Key.Subtract(unix).TotalMilliseconds,
                                value = x.Sum(y => y.Quantity)
                            })
               .ToList();

您也可以将其存储在字典中:

var quantities
    = db.Stocks.Find(id).Trades
               .GroupBy(x => x.Price.Date)
               .ToDictionary(x => x.Key, x => x.Sum(y => y.Quantity));

考虑到你在问题中的澄清,这可以工作:

var totalQty = 0;
var cumulatedQuantities =
    db.Stocks.Find(id).Trades
      .Select(t => new KeyValuePair<int, int>(t.Id, totalQty += t.Quantity)).ToList();

看起来像是Aggregate的工作

db.Stocks.Find(id).Trades
         .Aggregate(new List<Tuple<double,double>>(),
                    (result, next) => {
                                   var total = (result.Any() ? result.Last().Item2 : 0) + next.value;
                                   result.Add(Tuple.Create(next.date, total));
                                   return result;
                               });

您可能想稍微改变一下,比如使用匿名对象、特定类或Dictionary来存储结果,但这是基本模式。

如果Trades还没有按日期排序,那么你也应该这样做,通过在Aggregate之前添加.OrderBy(t => t.date)