给定单日日期 (dd-mm-yyyy) 的数据表(如下图左侧所示)。
将其转换为范围集合的最优雅方法是什么,将每种类型的连续天数分组(显示在右侧)?
我们可以假设初始数据按 TypeID 排序,然后按日期排序。
TypeID | Date -> TypeID | Start | End
1 | 01/02/2010 1 | 01/02/2010 | 03/02/2010
1 | 02/02/2010 2 | 03/02/2010 | 04/02/2010
1 | 03/02/2010 2 | 06/02/2010 | 06/02/2010
2 | 03/02/2010
2 | 04/02/2010
2 | 06/02/2010
我对 LINQ 并不特别在意,但我认为这可能是可行的方法?
如有任何帮助,我们将不胜感激!
请您参考如下方法:
当然有人会想出一个简洁的 LINQ 解决方案,但这是我的旧式解决方案。当然它有问题并且无法应对所有组合,拼凑起来并解决了问题但在任何方面都不优雅:-(
internal class SourceData
{
public int TypeId { get; set; }
public DateTime Date { get; set; }
}
internal class Result
{
public int TypeId { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
class Program
{
static void Main()
{
var a = new List<SourceData> {
new SourceData {TypeId = 1, Date = new DateTime(2010, 02, 01)},
new SourceData {TypeId = 1, Date = new DateTime(2010, 02, 02)},
new SourceData {TypeId = 1, Date = new DateTime(2010, 02, 03)},
new SourceData {TypeId = 2, Date = new DateTime(2010, 02, 03)},
new SourceData {TypeId = 2, Date = new DateTime(2010, 02, 04)},
new SourceData {TypeId = 2, Date = new DateTime(2010, 02, 06)}
};
var results = new List<Result>();
int currentTypeId = 1;
var rangeEndDate = new DateTime();
DateTime rangeStartDate = a[0].Date;
DateTime currentDate = a[0].Date;
for (int i = 1; i < a.Count() ; i++)
{
if (a[i].TypeId != currentTypeId)
{
results.Add(new Result() { TypeId = currentTypeId, StartDate = rangeStartDate, EndDate = rangeEndDate });
currentTypeId += 1;
rangeStartDate = a[i].Date;
}
TimeSpan tSpan = a[i].Date - currentDate;
int differenceInDays = tSpan.Days;
if(differenceInDays > 1)
{
results.Add(new Result { TypeId = currentTypeId, StartDate = rangeStartDate, EndDate = a[i-1].Date });
rangeStartDate = a[i].Date;
}
rangeEndDate = a[i].Date;
currentDate = a[i].Date;
}
results.Add(new Result { TypeId = currentTypeId, StartDate = rangeStartDate, EndDate = rangeEndDate });
Console.WriteLine("Output\n");
foreach (var r in results)
Console.WriteLine( string.Format( "{0} - {1} - {2}",r.TypeId,r.StartDate.ToShortDateString(),r.EndDate.ToShortDateString()));
Console.ReadLine();
}
}
给出以下输出:-
输出
1 - 2010 年 1 月 2 日 - 2010 年 2 月 3 日
2 - 2010 年 2 月 3 日 - 2010 年 2 月 4 日
2 - 06/02/2010 - 06/02/2010
