如何用LINQ将含重复键的List<Tuple<int, int>>转为Dictionary<int, List<int>>?
用LINQ优雅实现重复键元组列表转多值字典
嗨,这个需求用LINQ来实现真的很简洁!你已经用foreach搞定了,那我给你分享几种更优雅的LINQ写法:
方法一:GroupBy + ToDictionary(最常用)
这是最直观的实现方式,先按元组的第一个元素分组,再把分组转换成字典:
// 假设这是你的原始元组列表 var tupleList = new List<Tuple<int, int>> { Tuple.Create(1, 10), Tuple.Create(1, 20), Tuple.Create(2, 30), Tuple.Create(3, 40), Tuple.Create(2, 50) }; // LINQ转换代码 var multiValueDict = tupleList .GroupBy(tuple => tuple.Item1) // 按第一个int(键)分组 .ToDictionary( group => group.Key, // 字典的键就是分组的键 group => group.Select(tuple => tuple.Item2).ToList() // 字典的值是分组里所有第二个int的列表 );
为什么这个写法优雅?
- 声明式编程:你只需要告诉程序“按键分组,然后转成字典”,不用手动处理「键是否已存在」「新建列表添加元素」这些细节,代码更清晰。
- 链式调用:连贯的调用让逻辑一目了然,没有冗余的判断代码。
方法二:ToLookup 转 Dictionary(备选方案)
如果你只是需要一个“键对应多个值”的结构,ToLookup其实更直接,但它返回的是ILookup<TKey, TValue>接口。如果必须要Dictionary的话,可以再转一次:
// 先创建Lookup var lookup = tupleList.ToLookup(tuple => tuple.Item1, tuple => tuple.Item2); // 转成Dictionary var multiValueDict = lookup.ToDictionary(group => group.Key, group => group.ToList());
ILookup本身就支持键对应多个值的查询,比如lookup[1]直接就能拿到所有键为1的值列表,如果你不需要修改这个结构,直接用ILookup会更省事~
和foreach写法对比
原来的foreach需要手动判断字典里是否存在当前键,不存在就新建列表,存在就添加元素,代码会有不少重复的判断逻辑。而LINQ把这些底层操作都封装了,代码量少一半还多,逻辑也更一目了然。
内容的提问来源于stack exchange,提问作者Misha Zaslavsky
相关产品推荐
相关产品推荐

