C# 合并两个列表中的信息

C# 合并两个列表中的信息,c#,list,collections,C#,List,Collections,我有两个列表对象,一个记录通过,一个记录零件的失败。我构建了两个单独的列表,因为它们分别显示在Excel电子表格中 两个列表都包含ReportData对象,这些对象具有以下字段: DataDate (DateTime) quantity (int) rejected (int) cumulativeQuantity (int) cumulativeRejected (int) 在pass列表中,我记录了截止到该日期的日期、数量和累计相等性。被拒绝值和累积被拒绝值设置为零。对于失败的列表,我做了

我有两个列表对象,一个记录通过,一个记录零件的失败。我构建了两个单独的列表,因为它们分别显示在Excel电子表格中

两个列表都包含
ReportData
对象,这些对象具有以下字段:

DataDate (DateTime)
quantity (int)
rejected (int)
cumulativeQuantity (int)
cumulativeRejected (int)
在pass列表中,我记录了截止到该日期的日期、数量和累计相等性。被拒绝值和累积被拒绝值设置为零。对于失败的列表,我做了相反的操作

最后,我想将它们结合起来,得到一个包含所有日期的
列表
对象

我不想与列表相交,因为从技术上讲,没有交叉点。虽然两者中都可能存在日期,但对象不同。我考虑循环遍历pass列表,查找故障中存在的日期,然后记录它们的拒绝值和累积值。这导致的问题是,如果存在不存在的日期,我可能不知道为该日期设置什么

另一个问题是项目是否存在于失败中但未通过。在实践中,这不应该发生,但出于本例的意图和目的,它可能发生

有办法做到这一点吗?这几乎是一个交集和列表的并集的组合,我不知道该怎么办

编辑

如果有点不清楚,考虑两个列表:

pass:
   DataDate: 05/01/15 quantity: 10 cumQuantity: 10 rejected: 0 cumRejected: 0
   DataDate: 05/02/15 quantity: 15 cumQuantity: 25 rejected: 0 cumRejected: 0
   DataDate: 05/03/15 quantity: 10 cumQuantity: 35 rejected: 0 cumRejected: 0
   DataDate: 05/04/15 quantity: 15 cumQuantity: 50 rejected: 0 cumRejected: 0

fail:
   DataDate: 05/01/15 quantity: 0 cumQuantity: 0 rejected: 10 cumRejected: 10
   DataDate: 05/02/15 quantity: 0 cumQuantity: 0 rejected: 10 cumRejected: 20
   DataDate: 05/03/15 quantity: 0 cumQuantity: 0 rejected: 10 cumRejected: 30
   DataDate: 05/05/15 quantity: 0 cumQuantity: 0 rejected: 10 cumRejected: 40
如何获得如下所示的最终列表:

total:
   DataDate: 05/01/15 quantity: 10 cumQuantity: 10 rejected: 10 cumRejected: 10
   DataDate: 05/02/15 quantity: 15 cumQuantity: 25 rejected: 10 cumRejected: 20
   DataDate: 05/03/15 quantity: 10 cumQuantity: 35 rejected: 10 cumRejected: 30
   DataDate: 05/04/15 quantity: 15 cumQuantity: 50 rejected: 0 cumRejected: 30
   DataDate: 05/05/15 quantity: 0 cumQuantity: 50 rejected: 10 cumRejected: 40

您可以这样做(不是最有效的,但简短明了):

var组合=已通过
.Concat(失败)
.GroupBy(x=>x.DataDate)
.选择(x=>newreportdata{
DataDate=x.键,
数量=x.总和(rd=>rd.数量),
拒绝=x.Sum(rd=>rd.rejected),
CumulativeEquantity=x.Max(rd=>rd.CumulativeEquantity),//或和
cumulativeRejected=x.Max(rd=>rd.cumulativeRejected)//或和
}).ToList();
//为两个列表中不存在的日期填充“孔”。
对于(变量i=1;i
您可以这样做(不是最有效的,但简短明了):

var组合=已通过
.Concat(失败)
.GroupBy(x=>x.DataDate)
.选择(x=>newreportdata{
DataDate=x.键,
数量=x.总和(rd=>rd.数量),
拒绝=x.Sum(rd=>rd.rejected),
CumulativeEquantity=x.Max(rd=>rd.CumulativeEquantity),//或和
cumulativeRejected=x.Max(rd=>rd.cumulativeRejected)//或和
}).ToList();
//为两个列表中不存在的日期填充“孔”。
对于(变量i=1;i
我真的很喜欢,所以我将详细介绍一下:

(例如,如果您的日期范围很大,字典可以加快处理速度。这还假设没有重复的日期。。如果有,请告诉我,我会相应调整)

这假设您是两种不兼容的类型

我真的很喜欢,所以我将进一步介绍:

(例如,如果您的日期范围很大,字典可以加快处理速度。这还假设没有重复的日期。。如果有,请告诉我,我会相应调整)

这假设您是两种不兼容的类型


我问的问题有什么不清楚的地方?
List
就是你想要的。。你能展示一下你的代码的类结构是什么样的吗。。您发布的代码无效。。请显示与您的问题相关的所有相关代码。。您显示的5行代码是什么。。这代表了什么…??在返回ReportData的循环调用GetReportData(Date,Passed,Failed)中循环您安装的日期。@MethodMan我试图不夸大这个问题。类就是这四个字段,我列出了它们的名称和类型。集合只是一个
列表
对象。我已经编辑了这个问题,以显示可能出现在两个不同列表中的信息,以及我希望最终列表是什么样子的。。但是像这样做怎么样?使用Except方法根据日期获取通过和失败之间的差异。交叉通过和失败。将Except结果与Intersect合并??我的问题有什么不清楚的地方?
列表是您想要的。。你能展示一下你的代码的类结构是什么样的吗。。您发布的代码无效。。请显示与您的问题相关的所有相关代码。。您显示的5行代码是什么。。这代表了什么…??在返回ReportData的循环调用GetReportData(Date,Passed,Failed)中循环您安装的日期。@MethodMan我试图不夸大这个问题。类就是这四个字段,我列出了它们的名称和类型。集合只是一个
列表
对象。我已经编辑了这个问题,以显示可能出现在两个不同列表中的信息,以及我希望最终列表是什么样子的。。但是像这样做怎么样?使用Except方法根据日期获取通过和失败之间的差异。交叉通过和失败。将结果与Intersect结合起来??真是个好主意,我喜欢你填补空白的方式。这将是一段时间之前,我可以测试这个肯定,但我会让你知道
var combined = passed
    .Concat(failed)
    .GroupBy(x => x.DataDate)
    .Select(x => new ReportData {
        DataDate = x.Key,
        quantity = x.Sum(rd => rd.quantity),
        rejected = x.Sum(rd => rd.rejected),
        cumulativeQuantity = x.Max(rd => rd.cumulativeQuantity), // or Sum
        cumulativeRejected = x.Max(rd => rd.cumulativeRejected)  // or Sum
    }).ToList();

// Fill "holes" for dates not present in both lists.
for (var i = 1; i < combined.Count; i++)
{
    if (combined[i].cumulativeQuantity == 0)
        combined[i].cumulativeQuantity = combined[i - 1].cumulativeQuantity;
    if (combined[i].cumulativeRejected == 0)
        combined[i].cumulativeRejected = combined[i - 1].cumulativeRejected;
}
var passedDict = passed.ToDictionary(p => p.DataDate, p);
var failedDict = failed.ToDictionary(p => p.DataDate, p);

var startedOn = DateTime.....
var endedOn = DateTime....

var combined = Enumerable
  .Range(0, 1 + endedOn.Subtract(startedOn).Days)
  .Select(x => 
    {
      Pass pass;
      Fail fail;

      var result = new ReportData()
      result.DataDate = staredOn.AddDays(x),

      if (passedDict.TryGetValue(result.DataDate, out pass))
      {
        result.Quantity = pass.Quantity;
        result.CumulativeQuantity = pass.CumulativeQuantity;
      }

      if (failedDict.TryGetValue(result.DataDate, out fail))
      {
        result.Rejected= fail.Rejected;
        result.CumulativeRejected = fail.CumulativeRejected ;
      }

      return result;
    })
  .ToList();