C# 寻找两本词典之间的差异

C# 寻找两本词典之间的差异,c#,.net,linq,collections,dictionary,C#,.net,Linq,Collections,Dictionary,是否有LINQ方法来找出两个通用词典之间的差异? 与中相同,但使用通用词典。类似的内容 var dicOne = new Dictionary<string, string>(){ {"asdf", "asdf"}, {"few","faew"}}; var dicTwo = new Dictionary<string, string>(){ {"asdf", "asdf"}}; var unContained = dicOne.Where(x => !dicTw

是否有LINQ方法来找出两个通用词典之间的差异?
与中相同,但使用通用词典。

类似的内容

var dicOne = new Dictionary<string, string>(){ {"asdf", "asdf"}, {"few","faew"}};
var dicTwo = new Dictionary<string, string>(){ {"asdf", "asdf"}};

var unContained = dicOne.Where(x => !dicTwo.Contains(x));
var dicOne=newdictionary();
var dicTwo=newdictionary(){{“asdf”,“asdf”};
var unContained=dicOne.Where(x=>!dicTwo.Contains(x));

如果性能很重要,您可能希望使用Dictionary类的哈希查找来提高速度。我对一本有100万条目的词典进行了测试,对其进行了深度复制,并对副本进行了10次编辑(删除了5条,添加了5条)。[我有一项任务要做,那就是查找数据中的更改,然后只将更改推送到另一个函数。]

对于LINQ(参见Magnus的回答),秒表所用的时间约为3600ms。使用Dictionary.Contains()进行简单比较,所用的时间约为600ms。环境为Visual Studio 2017社区,在同一台机器上的ConsoleApp测试线束处于调试模式

您的里程数可能会有所不同,而且行数可能不多,因此这可能无关紧要,但对于较大的词典,使用Dictionary类的查找功能是值得的

在下面的示例中,dicA和dicB是您想要区分的两个相似的字典对象。dicAdd是A拥有但B中缺少的项的字典。dicDel是B包含但A不包含的项的字典。试着使用一些非常简单的测试字典,在那里你知道会发生什么,并且应该清楚地知道如何使用

    public static void DiffDictionaries<T, U>(
        Dictionary<T, U> dicA,
        Dictionary<T, U> dicB,
        Dictionary<T, U> dicAdd,
        Dictionary<T, U> dicDel)
    {
        // dicDel has entries that are in A, but not in B, 
        // ie they were deleted when moving from A to B
        diffDicSub<T, U>(dicA, dicB, dicDel);

        // dicAdd has entries that are in B, but not in A,
        // ie they were added when moving from A to B
        diffDicSub<T, U>(dicB, dicA, dicAdd);
    }

    private static void diffDicSub<T, U>(
        Dictionary<T, U> dicA,
        Dictionary<T, U> dicB,
        Dictionary<T, U> dicAExceptB)
    {
        // Walk A, and if any of the entries are not
        // in B, add them to the result dictionary.

        foreach (KeyValuePair<T, U> kvp in dicA)
        {
            if (!dicB.Contains(kvp))
            {
                dicAExceptB[kvp.Key] = kvp.Value;
            }
        }
    }
公共静态字典(
迪卡字典,
字典dicB,
字典迪卡德,
字典(迪德尔)
{
//dicDel的条目在A中,但不在B中,
//即从A移动到B时,它们被删除
diffDicSub(dicA、dicB、dicDel);
//dicAdd的条目在B中,但不在A中,
//即从A移动到B时添加的
diffDicSub(dicB、dicA、dicAdd);
}
专用静态空分复用器(
迪卡字典,
字典dicB,
词典(例外)
{
//走A步,如果有任何条目没有
//在B中,将它们添加到结果字典中。
foreach(dicA中的KeyValuePair kvp)
{
如果(!dicB.包含(kvp))
{
dicAExceptB[kvp.Key]=kvp.Value;
}
}
}

您可以使用
AsEnumerable
将词典“转换”为
IEnumerable
,然后使用链接问题中建议的解决方案。由于KeyValuePair是一个结构,它应该按值进行比较。您不需要
AsEnumerable
,因为这绝对不会进行转换。将intellisense方法限制为
IEnumerable
扩展,并允许在同样实现
IQueryable
的对象上使用
IEnumerable
扩展,而无需强制转换。
dic1.Except(x=>dic2.Contains(x)).Union(dic2.Except(x=>dic1.Contains(x))
,你想要更好的方法吗?@SaeedAmiri
除了
需要一个
IEnumerable
作为输入,而不是一个被授权者,只在
dictTwo
中不包括这些元素,但在
dictOne
中不包括这些元素。这个方法只比较键吗?@bto.rdz不,键和值。非常好,但不要忘记检查
null
这个答案可能需要更多的细节。没有解释,一行代码不是一个很好的答案。
    public static void DiffDictionaries<T, U>(
        Dictionary<T, U> dicA,
        Dictionary<T, U> dicB,
        Dictionary<T, U> dicAdd,
        Dictionary<T, U> dicDel)
    {
        // dicDel has entries that are in A, but not in B, 
        // ie they were deleted when moving from A to B
        diffDicSub<T, U>(dicA, dicB, dicDel);

        // dicAdd has entries that are in B, but not in A,
        // ie they were added when moving from A to B
        diffDicSub<T, U>(dicB, dicA, dicAdd);
    }

    private static void diffDicSub<T, U>(
        Dictionary<T, U> dicA,
        Dictionary<T, U> dicB,
        Dictionary<T, U> dicAExceptB)
    {
        // Walk A, and if any of the entries are not
        // in B, add them to the result dictionary.

        foreach (KeyValuePair<T, U> kvp in dicA)
        {
            if (!dicB.Contains(kvp))
            {
                dicAExceptB[kvp.Key] = kvp.Value;
            }
        }
    }