在 C# 中合并 2 个或多个字典 () 的最佳方法是什么?
(像 LINQ 这样的 3.0 功能很好)。Dictionary<TKey, TValue>
我正在考虑一个方法签名,如下所示:
public static Dictionary<TKey,TValue>
Merge<TKey,TValue>(Dictionary<TKey,TValue>[] dictionaries);
或
public static Dictionary<TKey,TValue>
Merge<TKey,TValue>(IEnumerable<Dictionary<TKey,TValue>> dictionaries);
关于重复键的处理:在发生冲突的情况下,只要哪个值一致,保存到字典中并不重要。
这部分取决于您在遇到重复项时想要发生的情况。例如,您可以执行以下操作:
var result = dictionaries.SelectMany(dict => dict)
.ToDictionary(pair => pair.Key, pair => pair.Value);
如果获得任何重复的密钥,这将引发异常。
编辑:如果你使用ToLookup,那么你将得到一个查找,每个键可以有多个值。然后,您可以将其转换为字典:
var result = dictionaries.SelectMany(dict => dict)
.ToLookup(pair => pair.Key, pair => pair.Value)
.ToDictionary(group => group.Key, group => group.First());
这有点丑陋 – 而且效率低下 – 但就代码而言,这是最快的方法。(诚然,我还没有测试过它。
当然,您可以编写自己的ToDictionary2扩展方法(使用更好的名称,但我现在没有时间考虑一个)-这并不难做到,只需覆盖(或忽略)重复键即可。重要的一点(在我看来)是使用 ,并意识到字典支持对其键/值对的迭代。SelectMany
我会这样做:
dictionaryFrom.ToList().ForEach(x => dictionaryTo.Add(x.Key, x.Value));
简单易行。根据这篇博文,它甚至比大多数循环都快,因为它的底层实现通过索引而不是枚举器访问元素(请参阅此答案)。
如果有重复项,它当然会抛出异常,因此您必须在合并之前进行检查。
如果有多个键(“右”键替换“左”键),这可以合并多个字典(如果需要)并保留类型(限制是它需要一个有意义的默认公共构造函数),这不会爆炸:
public static class DictionaryExtensions
{
// Works in C#3/VS2008:
// Returns a new dictionary of this ... others merged leftward.
// Keeps the type of 'this', which must be default-instantiable.
// Example:
// result = map.MergeLeft(other1, other2, ...)
public static T MergeLeft<T,K,V>(this T me, params IDictionary<K,V>[] others)
where T : IDictionary<K,V>, new()
{
T newMap = new T();
foreach (IDictionary<K,V> src in
(new List<IDictionary<K,V>> { me }).Concat(others)) {
// ^-- echk. Not quite there type-system.
foreach (KeyValuePair<K,V> p in src) {
newMap[p.Key] = p.Value;
}
}
return newMap;
}
}
模板简介:该模板名称为【在 C# 中合并字典】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【C#】栏目查找您需要的精美模板。