这是前一个问题的转发,该问题被错误地作为重复项关闭:
说我有两个相同类型的集合,类似于以下内容:
OldCollection:[{ID: 1 ,其他道具},{ID: 2 ,其他道具},{ID: 3 ,其他道具}]
NewCollection:[{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已添加。
这里是DotNetFiddle example,几乎可以满足我的要求。 小提琴的结果是:
[
{
"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"
}
}
]
答案 0 :(得分:3)
无论如何您都希望有一个完整的外部联接,但是您可以使用这种简单的方法:
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));
因此,首先创建两个字典以通过ID有效地查找旧对象和新对象。然后收集所有ID,并使用Select
来获取每个ID的旧对象/新对象。如果在词典中不可用,它将为元组项分配null
。