如何在C#中合并两个字典并对重复键合并对应值?
合并两个Dictionary<string, List>的实现方案
刚好处理过类似的需求,给你两种实用的实现方式,根据你的场景选择就行:
方法一:用LINQ快速实现(简洁高效)
如果你的场景不需要太复杂的自定义逻辑,用LINQ一行流就能搞定,代码简洁易读:
var mergedDict = dictA.Concat(dictB) .GroupBy(kv => kv.Key) .ToDictionary( group => group.Key, group => group.SelectMany(kv => kv.Value).ToList() );
逻辑拆解:
Concat(dictB):把两个字典的所有键值对合并成一个统一的序列GroupBy(kv => kv.Key):按照键(Key)对所有键值对分组,这样相同键的条目会被归到一组ToDictionary(...):把分组后的结果转换成新字典,每个键对应的 value 是分组里所有列表的元素通过SelectMany扁平化合并后的新列表
方法二:手动遍历(适合自定义逻辑场景)
如果需要对合并过程做更精细的控制(比如处理空列表、添加元素时做过滤等),手动遍历会更灵活:
// 先把dictA的内容复制到新字典里 var mergedDict = new Dictionary<string, List<int>>(dictA); foreach (var keyValuePair in dictB) { // 检查键是否已存在 if (mergedDict.TryGetValue(keyValuePair.Key, out var existingList)) { // 存在的话,把dictB里的列表元素追加到现有列表 existingList.AddRange(keyValuePair.Value); } else { // 不存在的话,添加新键值对(注意这里要创建列表副本,避免后续修改原dictB的列表影响合并结果) mergedDict.Add(keyValuePair.Key, new List<int>(keyValuePair.Value)); } }
额外提示:
- 如果需要合并后去重,可以在LINQ的
SelectMany后追加.Distinct().ToList(),或者手动遍历的AddRange后调用existingList = existingList.Distinct().ToList()(不过要注意去重会改变元素顺序,如果需要保留顺序的话得用其他方式) - 手动遍历里,不要直接用
mergedDict.Add(keyValuePair.Key, keyValuePair.Value),这样合并后的字典和原dictB的列表是同一个引用,后续修改原dictB的列表会同步影响合并结果,所以一定要创建副本
内容的提问来源于stack exchange,提问作者TMStackO
相关产品推荐
相关产品推荐

