我有这个循环逐个构建这些IEnumerables
,我希望能够优化它,以便它可以一次调用并构建所有这些IEnumerables
IEnumerable
而不是循环必须执行的列表。该代码按月对FilteredCases(一年中不同类型树木的情况)进行分组,并计算该月份与全年相比的树木百分比。我的问题是,我每年都会单独执行此操作,并希望通过将正确的数据组合在一起,在一个LINQ调用中执行此操作。
以下是代码:
var seriesDataLineList = new List<IEnumerable<SeriesDataPointArray>>();
foreach (var tree in trees)
{
IEnumerable<SeriesDataPointArray> seriesDataLine = months.Select(month => new SeriesDataPointArray()
{
X = month.LookupMonthName,
Y = new object[] { Math.Round(FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId && fc.LookupMonthId == month.LookupMonthId) / (double)FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId) * 100, 0) }
});
seriesDataLineList.Add(seriesDataLine);
}
我尝试使用LINQ执行此操作:
var test = from fc in FilteredCases
group fc by new { fc.Tree, fc.Month }
into casesGrouped
orderby casesGrouped.Key.Tree
select new { casesGrouped.Key.Tree, casesGrouped.Key.Month, count = casesGrouped.Count() };
但我不确定如何将这些内容合并为一个IEnuerable<SeriesDataPointArray>
答案 0 :(得分:0)
你上面提到的是循环和linq的混合,因为你将迭代与基于集合的逻辑混合在一起会让人感到困惑。如果将代码扩展为只是循环,您可能会发现更容易转换为linq。
作为所有循环
var seriesDataLineList = new List<SeriesDataPointArray>();
foreach (var tree in trees)
{
foreach (var month in months)
{
var seriesDataLine = new SeriesDataPointArray()
{
X = month.LookupMonthName,
Y = new double[] { Math.Round(FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId && fc.LookupMonthId == month.LookupMonthId) / (double)FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId) * 100, 0) }
};
seriesDataLineList.Add(seriesDataLine);
};
}
在所有循环中获得代码后,转换为linq非常简单。嵌套循环在功能上等同于笛卡尔积,在句法上可以通过多个不相关的语句来实现。
var results = from tree in trees
from month in months
select new SeriesDataPointArray()
{
X = month.LookupMonthName,
Y = new double[] { Math.Round(FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId && fc.LookupMonthId == month.LookupMonthId) / (double)FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId) * 100, 0) }
};
或者在lambda中,多个嵌套的select语句。你需要在某处使用SelectMany()来展平嵌套集合。
var results = trees.Select(tree =>
months.Select(month =>
new SeriesDataPointArray()
{
X = month.LookupMonthName,
Y = new double[] { Math.Round(FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId && fc.LookupMonthId == month.LookupMonthId) / (double)FilteredCases.Count(fc => fc.LookupTreeId == tree.LookupTreeId) * 100, 0) }
}
)
).SelectMany(x => x);