C# Linq合并两个字典

7
如何使用linq使下面的方法更加功能强大?
    public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
    {
        var e = new Dictionary<T, T>();

        a.Concat(b).ToList().ForEach(pair =>
        {
            e[pair.Key] = pair.Value;
        });

        return e;
    }

4
如果两个字典发生键冲突,您打算采取什么行动? - Eric J.
@ericj:使用了b的值。 - michaelr524
3个回答

15

为了继续你的重复内容丢弃方式,只需组成团队并在团队中拿走获胜的物品(比如最后一个)。

first.Concat(second)
  .GroupBy(kvp => kvp.Key, kvp => kvp.Value)
  .ToDictionary(g => g.Key, g => g.Last());

这实际上会产生相反的行为 - 来自“first”的值将被保留,而操作将始终从“second”获取值(即:g.Last()或反向连接)。 - Reed Copsey
@ReedCopsey 已被编辑包含,感谢。 - Amy B
1
@davidb 我认为这是最优雅的解决方案。 - michaelr524

4

你可以直接使用ToDictionary

public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
{
     return a.Concat(b).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

请注意,如果存在重复的键,这将引发异常。

如果需要处理重复的键,则需要决定如何处理。例如,以下代码将从“b”中删除重复项:

public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
{
     return a.Concat(b.Where(kvp => !a.ContainsKey(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

为了得到与原始行为相同的结果,您可以采用另一种方法(保留来自“b”中的KeyValuePair值):
public static Dictionary<T, T> MergeDict<T, T>(Dictionary<T, T> a, Dictionary<T, T> b)
{
     return b.Concat(a.Where(kvp => !b.ContainsKey(kvp.Key)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

对于重复项的处理方式不同。此版本会抛出异常。 - H H
是的 - 我编辑了以展示如何避免那个问题... - Reed Copsey
@reedcopsey 看起来不错,现在我想知道什么是最有效的解决方案 :) - michaelr524

0

或许是这样的。

public static IDictionary<T, U> Merge<T, U>(this IDictionary<T, U> first, IDictionary<T, U> second)
{
    return first.Concat(second).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接