解决Linq.ToDictionary()时的键重复问题
今天在使用 Linq 的 ToDictionary() 时发生了异常,提示:
System.ArgumentException: 已添加了具有相同键
因为以前一直没有遇到有相同键的情况,所以从来没关注过这个问题。然后写段试验来码来处理这个问题
问题再现
csclass 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() 来解决,所以改写了代码
cs// 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<> 的定义
cspublic interface ILookup<TKey, TElement>
: IEnumerable<IGrouping<TKey, TElement>>, IEnumerable public interface IGrouping<out TKey, out TElement>
: IEnumerable<TElement>, IEnumerable
自定义 ToDictionaryEx() 来解决
因为 ToLookup() 返回的结果包含太多枚举对象,所以不知道性能如何。如果不放心,可以自己写个 ToDictionaryEx() 来解决,当然也不敢保证性能就比 ToLookup() 好,要实验了才知道。
csstatic 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;
}
}
现在实验代码又该改改了
cs// 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()时的键重复问题的更多相关文章
- mysql insert插入时实现如果数据表中主键重复则更新,没有重复则插入的四种方法
[CSDN下载] Powerdesigner 设计主键code不能重复等问题 [CSDN博客] Oracle中用一个序列给两个表创建主键自增功能的后果 [CSDN博客] MySQL自增主键删除后重复问 ...
- Linux下Oracle中SqlPlus时上下左右键乱码问题的解决办法
window下的sqlplus可以通过箭头键,来回看历史命令,用起来非常的方便. 但是在Linux下,会出现各种乱码,非常不方便,如下图所示,每次打错一个字符就需要重新打一遍. 解决办法:rlwrap ...
- (转)mysql自增列导致主键重复问题分析
mysql自增列导致主键重复问题分析... 原文:http://www.cnblogs.com/cchust/p/3914935.html 前几天开发童鞋反馈一个利用load data infile ...
- (2.10)Mysql之SQL基础——约束及主键重复处理
(2.10)Mysql之SQL基础——约束及主键重复处理 关键词:mysql约束,批量插入数据主键冲突 [1]查看索引: show index from table_name; [2]查看有约束的列: ...
- C# Dictionary<TKey,TValue>如何添加键重复的内容
这里以Dictionary<string,string>为例 当我们实例化Dictionary<string,string>集合时,其中有一个重载构造方法如下: // // 摘 ...
- Entity Framework Code First 在Object Join Linq查询时出现全表查询的语句。
最近一个项目,使用微软的Entity Framework的ORM框架的项目,部署到现场后,出现了系统缓慢,多个客户端的内存溢出崩溃的问题. 打开了SQL Server Profiler(SQL Ser ...
- 【Transact-SQL】SQL Server自动把left join自动转化为inner join、以及关联时的数据重复问题
原文:[Transact-SQL]SQL Server自动把left join自动转化为inner join.以及关联时的数据重复问题 1.SQL Server自动把left join自动转化为inn ...
- 使用sequelize-auto 生成mysql 表的实体时主键没有 autoIncrement: true 属性
使用sequelize-auto 生成mysql 表时主键没有 autoIncrement: true 属性,这会导致插入数据时报错.看git上面是已经解决了的,解决方法是修改查询语句模板.我用的是0 ...
- 解决安装mysql时出现的三种问题
MySQL v5.0.96 for windows 安装版 链接:http://pan.baidu.com/s/1slmE2k9 密码:tadp MySQLAdministratort ...
随机推荐
- 四、 java循环结构
for循环结构: 格式:①初始化条件;②循环条件;③迭代条件;④循环体 for(①;②;③){ //④ } 执行过程:①-②-④-③-②-④-③-...-④-③-②,直至循环条件不满足,退出当前的循环 ...
- chroot下二进制程序迁移
#!/bin/bash # #define function#Copy binary programcp_bin(){ cmd_dir=${cmd_path%/*} [ ! -d /mnt/sysro ...
- XA事务与MySQL
XA事务就是两阶段提交的一种实现方式 XA规范主要定义了事务管理器TM,和资源管理器RM之间的接口 根据2PC的规范,将一次事务分割成两个阶段 1. prepare阶段 TM向所有RM发送prepar ...
- Hibernate游记——盘缠篇(jar包)
需要的jar包我都放我百度网盘了 jar(包含注解需要的jar)包传送门:http://pan.baidu.com/s/1o60OYvg
- Java开发者使用C++写程序踩的坑
笔者是一个很矛盾的人.平时用Java.但是一开始学习的时候学的是汇编语言,而且对C语言也很熟悉.为什么不学C++呢?是因为我可以完全用Java的编码规范去写C++.因此我不需要了解更多的诸如C++的命 ...
- 品质与合身 无须昂贵 | Tailorwoods在线男装定制
品质与合身 无须昂贵 | Tailorwoods在线男装定制 北京市朝阳区姚家园北一路八月照相馆2F
- systemtap学习笔记及疑问
http://blog.csdn.net/sunnybeike/article/details/7769663
- andriod打开摄像头和打开相册
package com.example.yanlei.picture; import android.support.v7.app.AppCompatActivity; import android. ...
- iOS -- SpriteKit框架之SKPhysicsBody的移动和连接
SKPhysicsBody的受力移动 SKPhysicsBody对象不同于SKSpriteNode对象.SKSpriteNode对象可以通过添加动作来进行移动,SKPhysicsBody对象却没有 ...
- Linux包括hash_map和hash_set的not declared问题
当在Linux下cpp文件包括hash_map或hash_set时.会出现"'hash_map' was not declared in this scope"问题. #inclu ...