合并C#中的字典

合并C#中的字典

合并两个或更多字典的最佳方法是什么(Dictionary<T1,T2>)在C#中(像LINQ这样的3.0特性很好)。

我正在考虑一个方法签名,大意是:

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);

编辑:从JaredPar和JonSkeet那里得到了一个很酷的解决方案,但是我在想一些处理重复密钥的方法。在冲突的情况下,只要是一致的,哪个值被保存到DECT中并不重要。


当年话下
浏览 1408回答 3
3回答

慕虎7371278

这在一定程度上取决于当你遇到重复时你想要发生什么。例如,您可以:var&nbsp;result&nbsp;=&nbsp;dictionaries.SelectMany(dict&nbsp;=>&nbsp;dict) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToDictionary(pair&nbsp;=>&nbsp;pair.Key,&nbsp;pair&nbsp;=>&nbsp;pair.Value);如果你有任何重复的钥匙就会爆炸。编辑:如果您使用ToLookup,那么您将得到一个查找,其中每个键可以有多个值。你,你们能然后将其转换为字典:var&nbsp;result&nbsp;=&nbsp;dictionaries.SelectMany(dict&nbsp;=>&nbsp;dict) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToLookup(pair&nbsp;=>&nbsp;pair.Key,&nbsp;pair&nbsp;=>&nbsp;pair.Value) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.ToDictionary(group&nbsp;=>&nbsp;group.Key,&nbsp;group&nbsp;=>&nbsp;group.First());这有点难看-而且效率很低-但这是在代码方面最快的方法。(无可否认,我还没有测试过它。)当然,您可以编写自己的ToDictionary2扩展方法(使用更好的名称,但我现在没有时间考虑)-这并不难,只需要覆盖(或忽略)重复的键。重要的一点(在我看来)是使用SelectMany,并意识到字典支持其键/值对的迭代。

慕娘9325324

我会这样做:dictionaryFrom.ToList().ForEach(x&nbsp;=>&nbsp;dictionaryTo.Add(x.Key,&nbsp;x.Value));简单容易。根据这篇博客文章它甚至比大多数循环都要快,因为它的底层实现通过索引而不是枚举器访问元素。(见这个答案).当然,如果存在重复项,则会抛出异常,因此在合并之前必须进行检查。

MMMHUHU

好吧,我去派对迟到了,但这是我的用武之地。如果有多个键(“连”键代替“左”键),可以合并许多字典(如果需要的话),并保留类型(限制是它需要有意义的默认公共构造函数),它就不会爆炸:public&nbsp;static&nbsp;class&nbsp;DictionaryExtensions{ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Works&nbsp;in&nbsp;C#3/VS2008: &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Returns&nbsp;a&nbsp;new&nbsp;dictionary&nbsp;of&nbsp;this&nbsp;...&nbsp;others&nbsp;merged&nbsp;leftward. &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Keeps&nbsp;the&nbsp;type&nbsp;of&nbsp;'this',&nbsp;which&nbsp;must&nbsp;be&nbsp;default-instantiable. &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Example:&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;result&nbsp;=&nbsp;map.MergeLeft(other1,&nbsp;other2,&nbsp;...) &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;T&nbsp;MergeLeft<T,K,V>(this&nbsp;T&nbsp;me,&nbsp;params&nbsp;IDictionary<K,V>[]&nbsp;others) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;T&nbsp;:&nbsp;IDictionary<K,V>,&nbsp;new() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;newMap&nbsp;=&nbsp;new&nbsp;T(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(IDictionary<K,V>&nbsp;src&nbsp;in &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(new&nbsp;List<IDictionary<K,V>>&nbsp;{&nbsp;me&nbsp;}).Concat(others))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;^--&nbsp;echk.&nbsp;Not&nbsp;quite&nbsp;there&nbsp;type-system. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(KeyValuePair<K,V>&nbsp;p&nbsp;in&nbsp;src)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newMap[p.Key]&nbsp;=&nbsp;p.Value; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;newMap; &nbsp;&nbsp;&nbsp;&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP