我有一个表,用于记录用户查看页面的时间。该表看起来像这样:
ID | Date
1 | 01/01/10 00:00:01.000
2 | 03/01/10 00:00:01.000
3 | 03/01/10 00:00:02.000
4 | 04/01/10 00:00:01.000
5 | 05/01/10 00:00:01.000
6 | 05/01/10 00:00:02.000
7 | 05/01/10 00:00:03.000
使用Linq-to-SQL我想计算一个页面被查看的最后一组连续日,但当然我不确定如何这样做。例如,对上面的数据运行查询应返回3.
非常感谢任何帮助:)
答案 0 :(得分:2)
这是测试数据。我在列表末尾添加了10月6日,以确保结果仅在上一个连续日期设置中获得。
List<DateTime> viewDates = new List<DateTime>();
viewDates.Add(new DateTime(10, 10, 1));
viewDates.Add(new DateTime(10, 10, 3));
viewDates.Add(new DateTime(10, 10, 3));
viewDates.Add(new DateTime(10, 10, 4));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 5));
viewDates.Add(new DateTime(10, 10, 6));
首先,我们需要找出最后一个连续日期:
var lastConsecutiveDate = viewDates
.Distinct()
.Reverse()
.SkipWhile(distinctDate => viewDates.Where(viewDate => (viewDate.Date == distinctDate.Date)).Count() < 2).FirstOrDefault();
我们在这里有两个选择,使用foreach
或LINQ
?与foreach
相比,LINQ
更具可读性。我将展示两种实现方式。
这是foreach
:
var consecutiveDates = new List<DateTime>();
foreach (var item in viewDates.Where(viewDate => viewDate <= lastConsecutiveDate).Distinct().OrderByDescending(a => a.Date))
{
//break if datediff is not 1
int count = consecutiveDates.Count;
if ((count > 0) && (consecutiveDates[count - 1].Date.AddDays(-1) != item.Date))
{
break;
}
consecutiveDates.Add(item);
}
这是LINQ
的实现,不太可读:
var consecutiveDates = viewDates
.Where(viewDate => viewDate <= lastConsecutiveDate)
.Distinct()
.OrderByDescending(viewDate => viewDate.Date)
.Aggregate
(
new { List = new List<DateTime>() },
(result, viewDate) =>
{
int count = result.List.Count;
if ((count > 0) && (result.List[count - 1].Date.AddDays(-1) != viewDate.Date))
{
return new { result.List };
}
result.List.Add(viewDate);
return new { result.List };
},
a => a.List
);
Console.WriteLine(consecutiveDates.Count());
将打印出“3”。
我期待对我的代码进行更多的重构,但是我休息了。