c# - 将 IList<DateTime> 中的连续日期组合成范围

标签 c# linq

  1. 我有一系列具有日期的对象。
  2. 使用类似的东西:

    IList<DateTime> dates =
        this.DateRanges
            .SelectMany(r => new [] { r.From, r.To })
            .Distinct()
            .OrderBy(d => d)
            .ToList();
    

    我可以获得所有日期,而不会重复任何日期。范围可能完全重叠、部分重叠(上部或下部重叠)、接触或完全不重叠。

  3. 现在我需要将此列表转换为另一个列表,以便每个连续的日期对在对的中间形成一个新生成的 DateTime 实例

    D1      D2      D3              D4  D5
        G1      G2          G3        G4
    

    Dn 是我在列表中的不同日期,Gm 日期是我想要的喜欢在它们中间生成。

问题

如何将单个日期的有序列表转换为成对日期,以便获得如下例所示的成对日期?我想使用 LINQ 而不是 for 循环来形成它们,后者可以完成同样的事情。由于表达式树执行延迟,使用 LINQ 可能会产生更高效的代码。

使用真实示例的额外说明

假设这是我的此类范围示例:

D1             D2     D3     D4   D5     D6          D11    D12
|--------------|      |------|    |------|           |------|
       D7                         D8
       |--------------------------|
D9                                              D10
|-----------------------------------------------|

第一步获取不同的日期将导致这些日期:

D1     D7      D2     D3     D4   D5     D6     D10  D11    D12

D9 和 D8 会脱落,因为它们是重复的。

下一步是结对(我不知道如何使用 LINQ 做到这一点):

D1-D7, D7-D2, D2-D3, D3-D4, D4-D5, D5-D6, D6-D10, (D10-D11), D11-D12

最后一步必须使用以下方法计算每对的日期:

Dnew = Dfrom + (Dto - Dfrom)/2

空范围问题

范围 D10-D11 最好省略。但是,如果省略它会导致代码过于复杂,则可以保留它并在之后通过单独检查将其排除。但是,如果最初可以将其排除在外,那就是应该做的。因此,如果您还提供有关如何形成排除空范围的对的信息,欢迎您也添加该信息。

最佳答案

您可以使用 Zip() :

var middleDates = dates.Zip(dates.Skip(1), 
                            (a, b) => (a.AddTicks((b - a).Ticks / 2)))
                       .ToList();

关于c# - 将 IList<DateTime> 中的连续日期组合成范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7634900/

相关文章:

c# - 如何使用 C# 中文本框的值查询 mySql 表?

c# - 将 Excel 导入 DataTable 字符串为空

c# - 套接字,接收序列化异常

c# - 为什么 LINQ 不包含 `distinct` 关键字?

c# - 如何使用 Linq 进行多级父子排序?

c# - Linq:方法无法转换为存储表达式

c# - Azure ServiceBus - 多次读取同一消息

angularjs - 将 IEnumerable 从 web api Controller 发送到 angular js

带投影的 Linq groupby 查询

linq - Nhibernate Linq In 子句