【问题标题】:Zip collections matching by ID按 ID 匹配的 Zip 集合
【发布时间】:2018-12-11 16:28:10
【问题描述】:

这是对上一个问题的重新发布,该问题被错误地关闭为重复:

假设我有两个相同类型的集合,类似于以下内容:

OldCollection: [{ID: 1, other props}, {ID: 2, other props}, {ID: 3,其他道具}]

NewCollection: [{ID: 1, other props}, {ID: 3, other props}, {ID: 4,其他道具}]

有没有办法压缩与 ID 匹配的集合以获得如下的元组结果:

[{OLD-ID1, NEW-ID1},
 {OLD-ID2, null},
 {OLD-ID3, NEW-ID3},
 {null, NEW-ID4}]

所以基本上我想将与 ID 匹配的集合压缩在一起,如果只有一个集合具有具有特定 ID 的条目,则元组应为该位置填写 null。

重要提示:这不是完整外部联接解决方案的副本。我不想合并我的结果,以便 Col1-ID1 与 Col2-ID1 合并。我只想对它们进行元组处理,这样我就可以并排看到它们。将其视为 Collection 1 是旧值,而 Collection 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"
    }
  }
]

【问题讨论】:

  • 为什么不是重复的?如果双方之一不可用,您想要一个完整的外部联接并分配null
  • 虽然它不是一个连接。我不想将 Collection1.ItemId1 与 Collection2.ItemId1 合并,我想将它们分开,只是让它们成组,这样我就可以并排单独看到它们。

标签: c# json linq


【解决方案1】:

无论如何你都想要一个完全外连接,但你可以使用这个简单的方法:

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 分配给元组项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-10
    • 1970-01-01
    相关资源
    最近更新 更多