【问题标题】:Combining information from two lists合并来自两个列表的信息
【发布时间】:2015-05-05 16:26:09
【问题描述】:

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

两个列表都包含ReportData 对象,它们具有字段:

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

在通过列表中,我记录了日期、数量和到该日期为止通过的累积数量。拒绝和累积拒绝值设置为零。我对失败的列表做相反的事情。

最后,我想将它们组合起来得到一个包含所有日期的 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

【问题讨论】:

  • 我在问什么不清楚?
  • List<ReportData> 是你想要的。你能展示你代码的类结构是什么样的吗?你发布的关于代码的内容不是有效的 C# 代码。请显示所有相关的与您的问题有关的代码..您显示的 5 行代码是什么..这代表什么..???
  • 循环遍历您感兴趣的日期,在循环调用 GetReportData(Date, Passed, Failed) 返回 ReportData。
  • @MethodMan 我试图不增加问题。类就是这四个字段,我列出了它们的名称和类型。该集合只是一个List<ReportData> 对象。我已编辑问题以显示可能出现在两个不同列表中的信息,以及我希望最终列表的外观。
  • 我对 C# 中的列表了解不多。但是做这样的事情怎么样?使用 except 方法根据日期获取 Pass 和 Failed 之间的差异。相交通过和失败。将 except 结果与 Intersect 联合??

标签: c# list collections


【解决方案1】:

你可以做这样的事情(不是最有效但简短明了):

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

【讨论】:

  • 真是个好主意,我喜欢你处理填补空白的方式。我还需要一段时间才能确定对此进行测试,但我会告诉你的。
  • 完美无瑕。非常感谢!
【解决方案2】:

我真的很喜欢Alex's Answer,所以我会扩展它:

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

这假设你的两种类型不兼容The &lt;TSource&gt; is not the same

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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2016-06-19
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多