如何计算积分?

时间:2014-05-03 22:41:59

标签: c# linq

如何构建"积分"函数来自Linq表达式,它返回一系列(时间|值)对?

E.g。我的Linq表达式导致(日期|数量)对的列表:

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

获得一系列(日期| 累计数量)的有效方法是什么,其中每条记录总共包含到该点的所有数量,加上当前数量?

EDIT1 - 使其具体化:以上查询返回的内容可能是

  • 0:(01.01.2012 | 10)
  • 1:(01.01.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));
}

不知何故,这感觉很难看......但它确实有用。

2 个答案:

答案 0 :(得分:2)

按日期分组,然后总计每组中的数量:

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

答案 1 :(得分:0)

看起来像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;
                               });

您可能希望稍微改变一下,例如使用匿名对象,特定类或字典来存储结果,但这是基本模式。

如果Trades尚未按日期排序,那么您也应该这样做,方法是在.OrderBy(t => t.date)之前添加Aggregate