结合两个列表中的信息

时间:2015-05-05 16:26:10

标签: c# list collections

我有两个List对象,一个录制通道和一个部件录制失败。我构建了两个单独的列表,因为它们在Excel电子表格中单独显示。

两个列表都包含ReportData个对象,其中包含字段:

DataDate (DateTime)
quantity (int)
rejected (int)
cumulativeQuantity (int)
cumulativeRejected (int)

在通过列表中,我记录了截至该日期的日期,数量和累计数量。 rejected和cumulativeRejected值设置为零。对于失败的清单,我做了相反的事情。

最后,我想将它们组合起来,以获得一个具有所有日期的List<ReportData>对象。

我不想与列表相交,因为从技术上讲,没有交叉点。虽然日期可能同时存在,但对象并不相同。我考虑循环遍历传递列表,并查找失败中存在的日期,然后记录其被拒绝和累计拒绝的值。这导致的问题是,如果有不存在的日期,我可能不知道该日期要设置cumulativeRejected的内容。

另一个问题是如果一个项目存在故障而不是通过。在实践中,这个不应该发生,但是对于这个例子的意图和目的,它可以。

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

修改

如果有点不清楚,请考虑两个清单:

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

2 个答案:

答案 0 :(得分:4)

你可以做这样的事情(不是最有效但短而清晰):

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;
}

答案 1 :(得分:0)

我非常喜欢Alex's Answer,所以我会扩展它:

(如果您的日期范围很大,字典可以加快处理速度,所以它们就在这里。这也假设没有重复日期。如果有让我知道,我会调整因此)

这假设您有两种类型不兼容The <TSource> is not the same

UPDATE MysterySpells SET SpellId = 589
WHERE MysteryId = 1 And ClassLevel = 2