C# 按ID匹配的Zip集合
这是前一个问题的复述,该问题被错误地作为副本关闭: 假设我有两个类型相同的集合,如下所示:C# 按ID匹配的Zip集合,c#,json,linq,C#,Json,Linq,这是前一个问题的复述,该问题被错误地作为副本关闭: 假设我有两个类型相同的集合,如下所示: [{OLD-ID1, NEW-ID1}, {OLD-ID2, null}, {OLD-ID3, NEW-ID3}, {null, NEW-ID4}] 旧集合:[{ID:1,其他道具},{ID:2,其他道具},{ID:3,其他道具}] 新集合:[{ID:1,其他道具},{ID:3,其他道具},{ID:4,其他道具}] 是否有一种方法可以压缩与ID匹配的集合以获得如下元组结果: [{OLD-ID1,
[{OLD-ID1, NEW-ID1},
{OLD-ID2, null},
{OLD-ID3, NEW-ID3},
{null, NEW-ID4}]
旧集合:[{ID:1,其他道具},{ID:2,其他道具},{ID:3,其他道具}]
新集合:[{ID:1,其他道具},{ID:3,其他道具},{ID:4,其他道具}]
是否有一种方法可以压缩与ID匹配的集合以获得如下元组结果:
[{OLD-ID1, NEW-ID1},
{OLD-ID2, null},
{OLD-ID3, NEW-ID3},
{null, NEW-ID4}]
所以基本上我想将集合压缩在一起,匹配ID,如果只有一个集合有一个具有特定ID的条目,元组应该为该点填充null
重要提示:这不是完整外部联接解决方案的副本。我不想合并我的结果,以便Col1-ID1与Col2-ID1合并。我只想把它们分成两组,这样我就能看到它们并排排列。将其视为集合1是旧值,集合2是新值。我想把它们配对成元组,这样我就可以看到ID1和ID3被更新,ID2被删除,ID4被添加
这是一个几乎符合我要求的程序。
这种做法的结果是:
[
{
"Item1": {
"id": 1,
"name": "firstOld"
},
"Item2": {
"id": 1,
"name": "firstNew"
}
},
{
"Item1": {
"id": 2,
"name": "secondOld"
},
"Item2": {
"id": 3,
"name": "thirdNew"
}
},
{
"Item1": {
"id": 3,
"name": "thirdOld"
},
"Item2": {
"id": 4,
"name": "fourthNew"
}
},
{
"Item1": null,
"Item2": {
"id": 5,
"name": "fifthNew"
}
}
]
我想要的是:
[
{
"Item1": {
"id": 1,
"name": "firstOld"
},
"Item2": {
"id": 1,
"name": "firstNew"
}
},
{
"Item1": {
"id": 2,
"name": "secondOld"
},
"Item2": null
},
{
"Item1": {
"id": 3,
"name": "thirdOld"
},
"Item2": {
"id": 3,
"name": "thirdNew"
}
},
{
"Item1": null,
"Item2": {
"id": 4,
"name": "fourthNew"
}
},
{
"Item1": null,
"Item2": {
"id": 5,
"name": "fifthNew"
}
}
]
您仍然需要一个完整的外部联接,但可以使用以下简单方法:
var oldByID = oldCollection.ToDictionary(x => x.Id);
var newByID = newCollection.ToDictionary(x => x.Id);
IEnumerable<int> allIds = oldByID.Keys.Union(newByID.Keys);
var oldAndNew = allIds.Select(id =>
(Old: oldByID.TryGetValue(id, out var oldObj) ? oldObj : null,
New: newByID.TryGetValue(id, out var newObj) ? newObj : null));
var oldByID=oldCollection.ToDictionary(x=>x.Id);
var newByID=newCollection.ToDictionary(x=>x.Id);
IEnumerable allIds=oldByID.Keys.Union(newbyd.Keys);
var oldAndNew=allIds.Select(id=>
(Old:oldByID.TryGetValue(id,out var oldObj)?oldObj:null,
New:newByID.TryGetValue(id,out var newObj)?newObj:null);
因此,首先创建两个字典,通过Id高效地查找新旧对象。然后收集所有Id并使用
Select
获取每个Id的旧/新对象。如果字典中没有该Id,则将null
分配给元组项。为什么它不是重复的?您需要一个完整的外部联接,如果两边都不可用,则分配null
。但它不是联接。我不想将Collection1.ItemId1与Collection2.ItemId1合并,我只想将它们分开,并将它们设置为元组,以便可以逐个并排查看。