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合并,我只想将它们分开,并将它们设置为元组,以便可以逐个并排查看。