[英]Compute running total in c# from linq query
I have spent a good few days learning linq and producing json results from my controller in mvc. 我花了很多天学习linq并从mvc中的控制器生成json结果。 I am now however stuck on an issue where I wish to rolling sum (cumulative sum) values of Y-Axis data to produce a year to date line chart.
但是,我现在停留在一个问题上,我希望滚动Y轴数据的总和(累积总和)值以生成年初至今的折线图。
My code at present to produce simple monthly data is as follows: 我目前产生简单的每月数据的代码如下:
//Generic Json For Graphs
public JsonResult GetJSONYTD(int kpiID)
{
var ViewData =
(from kpidata in departmentrepo.GetGraphData(kpiID)
select new DepartmentOverviewDetailsViewModel.GraphJSONViewModel
{
XData = kpidata.Year.Year1 + "-"
+ kpidata.Month.Real_Month_Int + "-01",
YData = kpidata.Value
});
var ChartData = ViewData.Select(
x => new object[] { x.XData, x.YData }).ToArray();
return Json(ChartData, JsonRequestBehavior.AllowGet);
}
The above produces the following array: 上面产生了以下数组:
[
["2011-10-01",0],
["2011-11-01",22],
["2011-12-01",22],
["2012-1-01",14],
["2012-2-01",14.4],
["2012-3-01",17.5],
["2012-4-01",20.3],
["2012-5-01",23.5],
["2012-6-01",24.5],
["2012-7-01",26.5]
]
I would like to output: 我想输出:
[
["2011-10-01",0],
["2011-11-01",22],
["2011-12-01",44],
["2012-1-01",38],
["2012-2-01",52.4],
etc
]
Any help? 有什么帮助吗?
Change your code to: 将您的代码更改为:
//Generic Json For Graphs //图的通用Json
public JsonResult GetJSONYTD(int kpiID)
{
var graphData = departmentrepo.GetGraphData(kpiID);
var ViewData = (from kpidata in graphData
select new DepartmentOverviewDetailsViewModel.GraphJSONViewModel
{
XData = kpidata.Year.Year1 + "-" + kpidata.Month.Real_Month_Int + "-01",
YData = graphData.Where(x=>x.Date<=kpidata.Date).Sum(x=>x.Value)
});
var ChartData = ViewData.Select(x => new object[] { x.XData, x.YData }).ToArray();
return Json(ChartData, JsonRequestBehavior.AllowGet);
}
The above code will store in YData the sum of all data points that have a data less than or equal to the current date. 上面的代码将在YData中存储数据小于或等于当前日期的所有数据点的总和。
You can do this inline with Aggregate: 您可以使用Aggregate内联执行此操作:
var rollingSum = ViewData.Aggregate(
// start with a list of a single model with value 0 (this avoids func having to deal with the empty list case
seed: new[] { new DepartmentOverviewDetailsViewModel.GraphJSONViewModel { XData = string.Empty, YData = 0.0 } }.ToList(),
// the aggregation function adds to the list a new tuple with the current date string
// and a cumulative sum value
func: (list, data) => {
list.Add(new DepartmentOverviewDetailsViewModel.GraphJSONViewModel { XData = data.XData, YData = data.YData + list[list.Count - 1].YData });
return list;
}
)
.Skip(1) // skip the first dummy value we seeded the list with
.ToArray();
Another option is to write a general purpose cumulative sum function and then used that: 另一种选择是编写通用累积和函数,然后使用该函数:
public static class MyEnumerableExtensions {
public static IEnumerable<double> CumulativeSum(this IEnumerable<double> @this) {
var sum = 0;
foreach (var value in @this) { sum += value; yield return sum; }
}
}
// then to compute the sum you want
var rollingSum = ViewData.Select(m => m.YData).CumulativeSum();
var rollingSumWithDates = ViewData.Zip(rollingSum, (m, sum) => new DepartmentOverviewDetailsViewModel.GraphJSONViewModel { XData = m.XData, YData = sum })
.ToArray();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.