之前在编程的时候一直都有用到Linq的GroupBy方法来给集合分组,但是一直不太清楚这个方法到底返回值是什么样的,今天找个时间来总结一下。
先看下官方给的释义:
// 摘要:
// 根据指定的键选择器函数对序列的元素进行分组。
//
// 返回结果:
// IEnumerable<IGrouping<TKey, TSource>> 在 C# 或 IEnumerable(Of IGrouping(Of TKey,
// TSource)) 中 Visual Basic 其中每个 System.Linq.IGrouping`2 对象包含一系列对象和一个密钥。
public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector);
主要看下它的返回值: IEnumerable<IGrouping<TKey, TSource>>
其中,IEnumerable<T>是可枚举的所有非泛型集合的基接口,比如我们经常用的List<T>等;
IGrouping<TKey, TSource> 官方给的定义是:表示具有公共键的对象的集合。点进去看下接口内部
//
// 摘要:
// 表示具有公共键的对象的集合。
//
// 类型参数:
// TKey:
// 键的类型 System.Linq.IGrouping`2。
//
// TElement:
// 中的值的类型 System.Linq.IGrouping`2。
public interface IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable
{
//
// 摘要:
// 获取的键 System.Linq.IGrouping`2。
//
// 返回结果:
// 键 System.Linq.IGrouping`2。
TKey Key { get; }
}
只有一个Key字段。再结合定义,可以知道返回值就是一个个集合,并且提供一个字段来表示公共键。
接下来通过代码验证下。
1.先准备一个使用的类
public class tabeldetail
{
//第一层
public string level1Name { get; set; }
//第二层
public string level2Name { get; set; }
//第三层
public string level3Name { get; set; }
//具体内容
public string content { get; set; }
}
2.根据这个类准备要使用的List
List<tabeldetail> resList= new List<tabeldetail>();
resList.Add(new tabeldetail
{
level1Name = "外观",
level2Name = "颜色",
level3Name = "白色",
content = "白色好看"
});
得到这么一个集合:
[
{"level1Name":"外观","level2Name":"颜色","level3Name":"白色","content":"白色好看"},
{"level1Name":"外观","level2Name":"颜色","level3Name":"红色","content":"红色好看"},
{"level1Name":"外观","level2Name":"颜色","level3Name":"蓝色","content":"蓝色好看"},
{"level1Name":"性价比","level2Name":"价格","level3Name":"","content":"价格不高"},
{"level1Name":"外观","level2Name":"形状","level3Name":"长方形","content":"长方形好看"},
{"level1Name":"外观","level2Name":"形状","level3Name":"圆形","content":"圆形好看"},
{"level1Name":"功能","level2Name":"容积","level3Name":"1L","content":"1L好看"},
{"level1Name":"功能","level2Name":"容积","level3Name":"2L","content":"2L好看"},
{"level1Name":"功能","level2Name":"容积","level3Name":"3L","content":"3L好看"},
{"level1Name":"功能","level2Name":"容积","level3Name":"4L","content":"4L好看"},
{"level1Name":"功能","level2Name":"质量","level3Name":"优秀","content":"优秀的产品"},
{"level1Name":"功能","level2Name":"质量","level3Name":"良好","content":"良好的产品"}
]
现在我们想要用GrouBy()来对这个集合进行修改,根据level1Name,Level2Name,Level3Name分成三层 。
运行时打断点看下返回情况:

可以看到group的key值就是当前的公共键“外观”和5个集合,这就是第一层的分类;
再接着看到group也可以使用GroupBy,说明group实际上还是一个集合,而返回的结果就是第二层的公共键“颜色”和三个集合。
这里用一个集合把返回的结果重新组装下,就可以获得需要的分好的三层的结果了
[{"Level1":"外观","obj":[{"Name":"颜色","details":[{"level1Name":"外观","level2Name":"颜色","level3Name":"白色","content":"白色好看"},{"level1Name":"外观","level2Name":"颜色","level3Name":"红色","content":"红色好看"},{"level1Name":"外观","level2Name":"颜色","level3Name":"蓝色","content":"蓝色好看"}]},{"Name":"形状","details":[{"level1Name":"外观","level2Name":"形状","level3Name":"长方形","content":"长方形好看"},{"level1Name":"外观","level2Name":"形状","level3Name":"圆形","content":"圆形好看"}]}]},{"Level1":"性价比","obj":[{"Name":"价格","details":[{"level1Name":"性价比","level2Name":"价格","level3Name":"","content":"价格不高"}]}]},{"Level1":"功能","obj":[{"Name":"容积","details":[{"level1Name":"功能","level2Name":"容积","level3Name":"1L","content":"1L好看"},{"level1Name":"功能","level2Name":"容积","level3Name":"2L","content":"2L好看"},{"level1Name":"功能","level2Name":"容积","level3Name":"3L","content":"3L好看"},{"level1Name":"功能","level2Name":"容积","level3Name":"4L","content":"4L好看"}]},{"Name":"质量","details":[{"level1Name":"功能","level2Name":"质量","level3Name":"优秀","content":"优秀的产品"},{"level1Name":"功能","level2Name":"质量","level3Name":"良好","content":"良好的产品"}]}]}]
具体的代码如下:
List<object> res = new List<object>();//最后需要返回的
var groups = resLists.GroupBy(t => t.level1Name);//第一层
foreach (var group in groups)
{
List<object> temp = new List<object>();
var list = group.GroupBy(y => y.level2Name);//第二层
foreach (var detail in list)
{
temp.Add(new
{
Name = detail.Key,
details = detail
});
}
res.Add(new
{
Level1 = group.Key,
obj = temp
});
}
string result = JsonConvert.SerializeObject(res);
本文探讨了C# Linq中的GroupBy方法,解释了其返回值类型IEnumerable<IGrouping<TKey, TSource>>的含义。通过示例展示了如何使用GroupBy对集合按level1Name, level2Name, level3Name进行三层分组,揭示了GroupBy在实际操作中如何层层嵌套以实现复杂的数据组织。最后给出了具体的分组操作代码。"
6526157,1072450,VS2005 C++ 内存泄漏检测方法,"['C++', '开发工具', '内存管理', '内存泄漏检测', 'Visual Studio']

724

被折叠的 条评论
为什么被折叠?



