让我们退后一步。您有两个字典,它们将 Individuals 键入一个整数。但是,您不是在比较相对字典的键,而是比较它们的值。这让我认为键不是唯一的。
听起来你想要的是两个字典的完全外部连接:
- 如果个人仅存在于 File1 中,请使用 File1 中的个人的键和值。
- 同样适用于仅在 File2 中的个人。
- 如果两个文件都包含相同的个人(按名称),则合并记录。
这可以通过一些 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 中的密钥,方法是根据合并的目录检查每个密钥。该代码如下所示:
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;
}
只要密钥不重复,这将安全地使用来自 _Individuals2 的密钥,因此应该使用来自 _Individuals2 的一些(但可能不是全部)密钥。这是否“更好”取决于具体情况。