Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较两个字典并将字典值添加到另一个字典C#_C#_Dictionary_Comparison - Fatal编程技术网

比较两个字典并将字典值添加到另一个字典C#

比较两个字典并将字典值添加到另一个字典C#,c#,dictionary,comparison,C#,Dictionary,Comparison,我正在试着比较两本加载的词典。每个个体都包含一个ID和一个对象 到目前为止,代码是 _Individuals1 = file1.fileIndividuals; _Individuals2 = file2.fileIndividuals; foreach (KeyValuePair<int, Individual> kvpInd in _Individuals1) { foreach (

我正在试着比较两本加载的词典。每个个体都包含一个ID和一个对象

到目前为止,代码是

            _Individuals1 = file1.fileIndividuals;
        _Individuals2 = file2.fileIndividuals;

        foreach (KeyValuePair<int, Individual> kvpInd in _Individuals1)
        {
            foreach (KeyValuePair<int, Individual> kvpInd2 in _Individuals2)
            {
                if (kvpInd.Value.name.name == kvpInd2.Value.name.name)
                {
                    similarInds.Add(kvpInd.Key, kvpInd.Value);
                }
            }
        }
\u Individuals1=file1.fileIndividuals;
_Individuals2=file2.fileIndividuals;
foreach(单个1中的键值对kvpInd)
{
foreach(单个2中的键值对kvpInd2)
{
if(kvpInd.Value.name.name==kvpInd2.Value.name.name)
{
添加(kvpInd.Key,kvpInd.Value);
}
}
}
我得到的错误是“已经添加了具有相同密钥的项。” 我有点明白为什么,但我不知道如何以不同的方式让它发挥作用。有人能帮忙吗


谢谢

这里的问题是,您对不同
字典
实例中的键和值之间的关系有一个错误的假设。多个条目很可能有不同的键,但值相同。如果在
\u Individuals2
中发生这种情况,那么您将在字典中添加两次相同的键。考虑

Map1

  • 关键1,价值狗
Map2

  • 关键2,价值狗
  • 关键3,价值狗
在这种情况下,Map2中的多个值具有Dog值。因此,我将根据您的算法执行以下操作

// 1:Dog matches 2:Dog
similarInds.Add(1, "Dog");
// 1:Dog matches 3:Dog
similarInds.Add(1, "Dog");
这里您似乎只想知道两个贴图之间相似的
单个
对象集。如果是这样,则只需存储该值并使用
设置
,以防止重复

var similarInds = new HashSet<Individual>();
...

similarInds.Add(kvpInd.Value);
var similarInds=new HashSet();
...
similarInds.Add(kvpInd.Value);

词典中可以有多个值相同的条目。您没有检查或比较钥匙

因此,在_Individuals2中有多个条目具有相同的值,尽管它们具有不同的键

我不知道您在这里做什么,但我认为您的键应该是使每个对象唯一的键,它们不应该真正比较值。如果你使用一个列表或类似的东西,你可以使用交集方法来返回它们的共同点

或者你可以用

_Individuals1.Values.Intersect(_Individuals2.Values);
此外,在处理泛型时,覆盖泛型中存储的对象的相等运算符几乎总是值得的。那么你就不必做这样的事情:

if (kvpInd.Value.name.name == kvpInd2.Value.name.name)

以下是使用lambdas的方法:

var similarInds = file1.fileIndividuals.
Where(kv1 => file2.fileIndividuals.Any(kv2 => kv1.Value.name.name == kv2.Value.name.name)).
ToDictionary(kv => kv.Key, kv => kv.Value);

让我们后退一步。您有两个字典,可以将个人设置为整数。但是,您不是在比较相关字典的键,而是比较它们的值。这让我觉得钥匙不是唯一的

听起来您想要的是两个词典的完整外部联接:

  • 如果某个人仅出现在文件1中,请使用文件1中该个人的键和值
  • 同上,仅适用于文件2中的个人
  • 如果两个文件包含相同的个人(按名称),则合并记录
这可以通过一些Linq来实现。要知道这并不是最有效的解决方案,但更容易理解发生了什么

//get records from 1 that aren't in 2
var left = _Individuals1.Where(l=>!_Individuals2.Any(r=>l.Value.Name == r.Value.Name));
//get records that appear in both 1 and 2, 
//using the select clause to "merge" the data you want from each side
var join = from l in _Individuals1
           join r in _Individuals2 on l.Value.Name equals r.Value.Name
           select new KeyValuePair<int, Individual>(l.Key, r.Value);
//get records from 2 that aren't in 1
var right = _Individuals2.Where(r=>!_Individuals1.Any(l=>l.Value.Name == r.Value.Name));

//Now, the keys from the left and join enumerables should be consistent,
//because we used the keys from _Individuals1 in both of them.
var merged = left.Concat(join).ToDictionary(x=>x.Key, x=>x.Value);

//BUT, keys from records that only existed in 2 may have duplicate keys, 
//so don't trust them
var maxKey = merged.Keys.Max();
foreach(var r in right)
   merged.Add(++maxKey, r.Value);

这将安全地使用来自_Individuals2的密钥,只要密钥不是重复的,因此应该使用来自_Individuals2的一些(但可能不是全部)密钥。这是否“更好”取决于具体情况。

name.name
有多个点击时会发生什么?似乎intersect方法效果最好:)谢谢!l.Value.Name==r.Value.Name上的_Individuals2中的行join r上有错误:(我认为它不喜欢r.Value.name partEdited;您必须使用关键字
equals
,而不是
=
运算符。连接条件的规范不是一个表达式;它定义了两个枚举的投影,在比较时必须相等。如果您查看找到更清晰的场景;您需要提供两个lambda,返回“内部键”和“外部键”。我不喜欢尝试var similarInds=new Set();显然Set不喜欢exist@user1290653对不起,应该是
HashSet
。更新了我的答案,然后如何将其创建到列表框的数据源中(lstIndividuals.DataSource)@user1290653要将其放入列表框中,您可能需要首先通过
.ToList()
@user1290653将其转换回
列表
,但您希望新字典中的键是什么?
var maxKey = merged.Keys.Max();
foreach(var r in right)
   if(merged.ContainsKey(r.Key))
      merged.Add(++maxKey, r.Value);
   else
   {
      merged.Add(r.Key, r.Value);
      maxKey = r.Key > maxKey ? r.Key : maxKey;
   }