如何使用LINQ对含Dictionary的List按Date分组并计算数值平均值?
解决按DateTime分组并计算Dictionary中数值字段平均值的问题
我来帮你梳理下当前的问题,并给出具体的解决方案:
首先,修正集合类型问题
你之前用了List<object>来存储字典,这导致你无法直接访问m["date"]——因为m是object类型,没有索引器。你需要把集合类型改成List<Dictionary<string, object>>,这样每个元素都是明确的字典类型,就能正常访问键值对了。
然后,正确实现分组与平均值计算
你的核心需求是按date分组,然后对每个分组里的其他decimal类型字段计算平均值。这里需要先按date分组,再对每个分组内的字段单独聚合。
完整代码示例:
// 第一步:修正集合类型,存储Dictionary而非object List<Dictionary<string, object>> dataList = new List<Dictionary<string, object>>(); // 假设你有多个这样的字典要添加(模拟你的循环逻辑) foreach (var jsonItem in yourJsonCollection) // yourJsonCollection是你的原始数据集合 { Dictionary<string, object> dict = new Dictionary<string, object>(); DateTime date = // 这里替换成你的date值,比如DateTime.Parse(jsonItem["date"].ToString()) dict.Add("date", date); foreach (var field in jsonItem) { // 假设json里的字段都是decimal可转换的数值,且不包含"date"(避免重复键) if (field.Key != "date") { dict.Add(field.Key, field.Value); } } dataList.Add(dict); } // 第二步:按date分组并计算各字段平均值 var groupedAverages = dataList .GroupBy(item => (DateTime)item["date"]) // 按date分组 .Select(group => new { Date = group.Key, FieldAverages = group // 提取所有非"date"的键值对,并扁平化集合 .SelectMany(dict => dict.Where(kv => kv.Key != "date")) // 按字段名分组,同一字段的所有值归为一组 .GroupBy(kv => kv.Key) // 转换为字典:键是字段名,值是该字段的平均值 .ToDictionary( fieldGroup => fieldGroup.Key, fieldGroup => fieldGroup.Average(kv => Convert.ToDecimal(kv.Value)) ) }) .ToList();
关键细节说明
- 集合类型修正:把
List<object>改成List<Dictionary<string, object>>后,item["date"]就能正常访问,因为item是明确的字典类型。 - 扁平化与二次分组:用
SelectMany把每个字典里的非date键值对提取出来并合并成一个集合,再按字段名二次分组,这样就能对每个字段单独计算平均值。 - 安全类型转换:如果你的数据可能存在非数值情况,可以用
decimal.TryParse做安全转换,避免报错:
fieldGroup.Average(kv => { if (decimal.TryParse(kv.Value.ToString(), out decimal val)) return val; return 0; // 或者根据需求处理无效值,比如抛出异常 })
示例输出
针对你给出的示例数据:
第一个字典:{"date": 05/29/2015 05:50:06, "Processing time": 6, "Disk usage": 2} 第二个字典:{"date": 05/29/2015 05:50:06, "Processing time": 8, "Disk usage": 4}
分组后会得到:
{ Date: 05/29/2015 05:50:06, FieldAverages: { "Processing time": 7, "Disk usage": 3 } }
内容的提问来源于stack exchange,提问作者Hugo Silva
相关产品推荐
相关产品推荐

