我们假设我有一个日期列表
01/01/2014,02/01/2014,08/01/2014,10/01/2014,11/01/2014,12/01/2014
如何获得连续项目的限制:
在我们的案例中应该是:
[01/01/2014,02/01/2014],
[08/01/2014],
[10/01/2014,12/01/2014]
我更喜欢Linq的解决方案。
答案 0 :(得分:2)
我不认为LINQ有一个优雅/简单的解决方案。但循环可以做到这一点:
List<DateTime> dates = new List<DateTime>() {
new DateTime(2014, 1, 1),
new DateTime(2014, 1, 2),
new DateTime(2014, 1, 8),
new DateTime(2014, 1, 10),
new DateTime(2014, 1, 11),
new DateTime(2014, 1, 12)
};
List<List<DateTime>> limits = new List<List<DateTime>>();
foreach (DateTime date in dates)
{
if (!limits.Any() || limits.Last().Last().AddDays(1) < date)
{
// add new limit group with the current date as startdate
limits.Add(new List<DateTime>() { date });
}
else
{
if (limits.Last().Count == 1)
{
// add the current date as new end date for the last limit group
limits.Last().Add(date);
}
else
{
// replace end date from last limit group with the current date
limits.Last()[1] = date;
}
}
}
答案 1 :(得分:2)
这可以在Linq中完成,这是一个完整的工作示例: 只是证明这是可能的,而不是说它是个好主意......
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
namespace Sandbox
{
public class Program
{
public static void Main(string[] args)
{
List<DateTime> dates = new List<DateTime>();
dates.Add(new DateTime(2014, 1, 1));
dates.Add(new DateTime(2014, 1, 2));
dates.Add(new DateTime(2014, 1, 8));
dates.Add(new DateTime(2014, 1, 10));
dates.Add(new DateTime(2014, 1, 11));
dates.Add(new DateTime(2014, 1, 12));
var values =
dates.Select(dt => new DateRange(dt, dt))
.Distinct(new DateConsecutiveComparer()).ToArray();
foreach (var range in values)
{
Console.WriteLine(range);
}
Console.ReadKey();
}
}
public class DateRange
{
public DateTime End { get; set; }
public DateTime Start { get; set; }
public DateRange(DateTime end, DateTime start)
{
End = end;
Start = start;
}
public override string ToString()
{
if (Start == End)
return "[" + Start.ToString("MM/dd/yyyy") + "]";
return "[" + Start.ToString("MM/dd/yyyy") + "," + End.ToString("MM/dd/yyyy") + "]";
}
public override int GetHashCode()
{
return Tuple.Create(Start, End).GetHashCode();
}
}
public class DateConsecutiveComparer : IEqualityComparer<DateRange>
{
public bool Equals(DateRange x, DateRange y)
{
if (x.End.AddDays(1) == y.Start)
{
x.End = y.End;
return true;
}
else if (y.End.AddDays(1) == x.Start)
{
y.End = x.End;
return true;
}
else
return false;
}
public int GetHashCode(DateRange obj)
{
return 1;
}
}
}
答案 2 :(得分:0)
代码不简单。无法用Linq实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
namespace ConsoleApplication56
{
class Program
{
static void Main(string[] args)
{
List<DateTime> dates = new List<DateTime>(){
DateTime.Parse("01/01/2014"),
DateTime.Parse("02/01/2014"),
DateTime.Parse("08/01/2014"),
DateTime.Parse("10/01/2014"),
DateTime.Parse("11/01/2014"),
DateTime.Parse("12/01/2014")
}.OrderBy(x => x).ToList();
List<DateRange> ranges = new List<DateRange>();
DateTime previousDate = new DateTime();
DateRange newRange = null;
for (int index = 0; index < dates.Count; index++)
{
if (index == 0)
{
previousDate = dates[0];
newRange = new DateRange() { startDate = dates[index]};
ranges.Add(newRange);
}
else
{
if (index == dates.Count - 1)
{
if (IsConsecutive(previousDate, dates[index]))
{
newRange.endDate = dates[index];
}
else
{
if (index != 1)
{
newRange.endDate = dates[index - 1];
}
newRange = new DateRange() { startDate = dates[index] };
ranges.Add(newRange);
}
}
else
{
if (!IsConsecutive(previousDate, dates[index]))
{
if (index != 1)
{
if(newRange.startDate != dates[index - 1])
newRange.endDate = dates[index - 1];
}
newRange = new DateRange() { startDate = dates[index] };
ranges.Add(newRange);
}
previousDate = dates[index];
}
}
}
}
static Boolean IsConsecutive(DateTime firstDate, DateTime secondDate)
{
if((new DateTime(firstDate.Year, firstDate.Month, 1)).AddMonths(1) == (new DateTime(secondDate.Year, secondDate.Month, 1)))
{
return true;
}
else
{
return false;
}
}
}
public class DateRange
{
public DateTime startDate { get; set; }
public DateTime endDate { get; set; }
}
}