今天在使用 Linq 的 ToDictionary() 时发生了异常,提示:

System.ArgumentException: 已添加了具有相同键

因为以前一直没有遇到有相同键的情况,所以从来没关注过这个问题。然后写段试验来码来处理这个问题

问题再现

class Program
{public static void Main(string[] args){var data = new[]{Tuple.Create("001", "James"),Tuple.Create("002", "Linda"),Tuple.Create("003", "Frank"),Tuple.Create("004", "Jack"),Tuple.Create("002", "Rose"),Tuple.Create("001", "Lynn"),Tuple.Create("008", "Luke")};var dict = data.ToDictionary(t => t.Item1, t => t.Item2);// 这里就抛异常了// System.ArgumentException: 已添加了具有相同键的foreach (var pair in dict){// 不要见怪,用了 C# 6.0 的语法Console.WriteLine($"{pair.Key} = {pair.Value}");}}
}

使用 ToLookup() 解决

原来 ToDictionary() 不会处理重复键,也没有提供多的参数来处理重复键。想了一下,这种问题大概应该用 ToLookup() 来解决,所以改写了代码

        // var dict = data.ToDictionary(t => t.Item1, t => t.Item2);// System.ArgumentException: 已添加了具有相同键的var dict = data.ToLookup(t => t.Item1, t => t.Item2).ToDictionary(t => t.Key, t => t.First());

ToLookup() 返回的是一个 ILookup<> 接口,看定义是一个 IGrouping<> 接口的枚举。IGrouping<> 本身也是一个 IEnumerable<>,具有 Key 属性。因为 IGrouping<> 将具有同一个键的所有元素都包含在内了,所以在生成 Dictionary 的时候只取其中一个元素,根据上下文需要,可以取 First(),或者 Last()

这是 ILookup<>IGrouping<> 的定义

public interface ILookup<TKey, TElement>: IEnumerable<IGrouping<TKey, TElement>>, IEnumerablepublic interface IGrouping<out TKey, out TElement>: IEnumerable<TElement>, IEnumerable

自定义 ToDictionaryEx() 来解决

因为 ToLookup() 返回的结果包含太多枚举对象,所以不知道性能如何。如果不放心,可以自己写个 ToDictionaryEx() 来解决,当然也不敢保证性能就比 ToLookup() 好,要实验了才知道。

static class ToDictionaryExtentions
{public static IDictionary<TKey, TValue> ToDictionaryEx<TElement, TKey, TValue>(this IEnumerable<TElement> source,Func<TElement, TKey> keyGetter,Func<TElement, TValue> valueGetter){IDictionary<TKey, TValue> dict = new Dictionary<TKey, TValue>();foreach (var e in source){var key = keyGetter(e);if (dict.ContainsKey(key)){continue;}dict.Add(key, valueGetter(e));}return dict;}
}

现在实验代码又该改改了

        // var dict = data.ToDictionary(t => t.Item1, t => t.Item2);// System.ArgumentException: 已添加了具有相同键的//var dict = data.ToLookup(t => t.Item1, t => t.Item2)//    .ToDictionary(t => t.Key, t => t.First());var dict = data.ToDictionaryEx(t => t.Item1, t => t.Item2);

性能

没有测试性能的问题,等暴露了性能问题再来测试吧

解决Linq.ToDictionary()时的键重复问题相关推荐

  1. sqlserver插入数据时如何忽略主键重复的数据

    我们都知道,主键具有唯一性,所以当插入数据时主键不能重复,但是这就会产生一个问题,那就是如果一次插入大量数据集时,这个数据集跟当前数据库有一些数据时重复的,这样插入的时候会产生主键冲突.那么如何忽略这 ...

  2. springboot 主键重复导致数据重复_程序员:MySQL处理插入过程中主键或唯一键重复值的解决办法

    向MySQL插入数据有时会遇到主键重复的场景,原来的做法是先在程序代码中SELECT一下,判断是否存在指定主键或唯一键的数据,如果没有则插入,有的话则执行UPDATE操作,或另外一套逻辑,这种方法是不 ...

  3. DB2添加数据时主键、唯一键冲突的解决方法

    DB2添加数据时主键.唯一键冲突的解决方法 参考文章: (1)DB2添加数据时主键.唯一键冲突的解决方法 (2)https://www.cnblogs.com/equation/articles/91 ...

  4. 计算机键盘重复,win7系统电脑键盘打字时总是出现重复字符的解决方法

    很多小伙伴都遇到过win7系统电脑键盘打字时总是出现重复字符的困惑吧,一些朋友看过网上零散的win7系统电脑键盘打字时总是出现重复字符的处理方法,并没有完完全全明白win7系统电脑键盘打字时总是出现重 ...

  5. 微信h5页面提交表单后返回键重复提交的问题

    微信h5页面提交表单后返回键重复提交的问题 问题描述:h5表单提交保存成功之后,手机返回后原来的页面还能提交表单. 示例: mui.post('savexxxx',data,function(res) ...

  6. 解决oracle主键问题,解决renren-security使用oracle主键问题

    解决renren-security使用oracle主键问题 分享 未结 1  808 LancCJ 2019-11-04 悬赏:20积分 下载项目,直接配置oracle数据库,在配置文件中使用 id ...

  7. 一起来玩树莓派--解决树莓派启动时屏幕不亮的问题

    解决树莓派启动时屏幕不亮的问题 问题描述 问题分析 解决方法 问题描述 最近因为比赛需要入手了一款树莓派3B+(没买4代的原因是还有一个月才能到货,哭),兴奋的不得了,但是在装系统的时候就遇到了一个耽 ...

  8. vue重复路由_解决vue路由name同名,路由重复的问题

    在项目中,想让路由后缀为空,或者index的时候,都跳转到路由为index的页面,于是在router中如下配置 routes: [{ path: '/', name: 'index', compone ...

  9. JavaScript通过变量设置对象键[重复]

    本文翻译自:JavaScript set object key by variable [duplicate] This question already has answers here : 这个问 ...

最新文章

  1. golang中的strings.Contains
  2. 14.6 设置后台线程
  3. (chap6 Http首部) 响应首部字段 AllowCt-EncodingCt-LanguageCt-LengthCt-Location
  4. Web前端人员如何面试?常见vue面试题有哪些?
  5. win系统下mysql忘记root账户密码的解决办法
  6. zabbix mysql版本号_zabbix 监控mysql5.6版本 及主从
  7. JavaScript 学习笔记— —Date对象
  8. 江苏师范大学科文学院计算机科学与技术,2019江苏师范大学科文学院专业排名...
  9. 虚拟机下安装ubuntu
  10. Kali-DDoS工具集合
  11. Scrum板与Kanban如何抉择?敏捷工具:SHSYdsjgyadtgad
  12. leetcode——回溯
  13. 书论51 朱文长《续书断》
  14. GAN ZOO - 第1节: 分析GAN的缺陷与改进方向,介绍典型的改进模型:CGAN、InfoGAN
  15. windows部署hadoop环境
  16. bulldog-1靶机 write up 源码 MD5解密得到密码到后台 命令执行绕过 反弹shell string分析文件得到密码提权
  17. < Linux >:shell命令初步认识,Linux权限
  18. svg标记marker
  19. mlag 堆叠_华为CE交换机M-LAG配置
  20. matlab 统计基本函数 var方差

热门文章

  1. PostgreSQL数据库中跨库访问解决方案
  2. DB2 sql报错后查证原因与解决问题的方法
  3. 移动端高清适配方案(解决图片模糊问题、1px细线问题)
  4. MySQL中 Data truncated for column ‘xxx‘解决方法
  5. 为什么我的程序在完全循环8192个元素时会变慢?
  6. python结束线程类_Python线程指南(转)
  7. Java:JDBC(Mysql)
  8. python图像压缩主成分分析实例_python机器学习API介绍13: 数据降维及主成分分析...
  9. uniapp实现瀑布流基本写法
  10. 力扣——合并两个有序数组