什么是在表格中聚合列值的LINQ方式,其中每一行都是Dictionary<ColumnT, ValueT>
?
数据表的格式为
2010 | 2011
A 11 | 12
B 21 | 22
这表示为词典列表:
var A = new Dictionary<String, int>();
A.Add("2010", 11);
A.Add("2011" 12),
var B = new Dictionary<String, int>();
A.Add("2010", 21);
A.Add("2011" 22),
var table = List<Dictionary<String,int>>() { A, B };
如何生成汇总来自其他行的所有列的总计行?总计行也可以像其他行一样Dictionary<String, int>
。
旧式的方式是:
var totalsRow = new Dictionary<String, int>();
foreach(Dictionary<String, int> row in table)
{
foreach(var cell in row)
{
// Get running sum (add if not present)
int TValue= 0;
if (!totalsRow.TryGetValue(cell.Key, out cellValue))
{
totalsRow.Add(cell.Key, 0);
}
// Increment using an aggregation function (e.g. sum)
totalsRow[cell.Key] = AggregationFunc(totalsRow[cell.Key], cellValue);
}
}
有没有更简洁的LINQ方式呢?
如果没有,那么定义扩展方法(在Dictionary上)以包装上述代码的最类似LINQ的方法是什么?
澄清:AggregationFunc
是获取正在运行的总计和下一个项目值并生成新的运行总计的任何函数,例如:
int Sum(int sum, int nextValue) { return sum + nextValue; }
答案 0 :(得分:4)
我认为你的最后一行实际上是:
totalsRow[cell.Key] = AggregationFunc(runningValue, cell.Value);
因为否则,您没有在任何地方使用嵌入字典的整数值。
你可以这样做:
var totalsRow = table.SelectMany(row => row)
.GroupBy(kvp => kvp.Key)
.ToDictionary(group => group.Key,
group => group.Sum(kvp => kvp.Value));
如果要保留AggregationFunc,请将第二个参数替换为ToDictionary
:
group => group.Aggregate(0,
(runningValue, nextKvp) => AggregationFunc(runningValue, nextKvp.Value))
这个想法是:
答案 1 :(得分:4)
这是:
var totals = table
.SelectMany(_ => _)
.GroupBy(_ => _.Key, _ => _.Value)
.ToDictionary(
group => group.Key,
group => group.Aggregate(AggregationFunc));