c#限制连续项-Linq

c#限制连续项-Linq,c#,linq,list,date,C#,Linq,List,Date,让我们假设我有一个日期列表 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的解决方案。我认为没有一个使用Linq的优雅/简单的解决方案。但循环可以做到这一点: List<DateTime> dates

让我们假设我有一个日期列表

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的解决方案。

我认为没有一个使用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;
        }
    }
}
列表日期=新列表(){
新日期时间(2014年1月1日),
新日期时间(2014年1月2日),
新日期时间(2014年1月8日),
新日期时间(2014年1月10日),
新日期时间(2014年1月11日),
新日期时间(2014年1月12日)
};
列表限制=新列表();
foreach(日期时间日期,以日期为单位)
{
如果(!limits.Any()| | limits.Last().Last().AddDays(1)<日期)
{
//添加当前日期为startdate的新限额组
添加(新列表(){date});
}
其他的
{
if(limits.Last().Count==1)
{
//将当前日期添加为最后一个限额组的新结束日期
limits.Last().Add(日期);
}
其他的
{
//将上一个限额组的结束日期替换为当前日期
limits.Last()[1]=日期;
}
}
}

代码并不简单。无法使用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; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统数据;
使用System.Xml;
命名空间控制台应用程序56
{
班级计划
{
静态void Main(字符串[]参数)
{
列表日期=新列表(){
DateTime.Parse(“2014年1月1日”),
DateTime.Parse(“2014年1月2日”),
DateTime.Parse(“08/01/2014”),
DateTime.Parse(“10/01/2014”),
DateTime.Parse(“11/01/2014”),
DateTime.Parse(“2014年1月12日”)
}.OrderBy(x=>x).ToList();
列表范围=新列表();
DateTime previousDate=新日期时间();
DateRange newRange=null;
for(int index=0;index
这可以在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;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
使用系统数字;
名称空间沙盒
{
公共课程
{
公共静态void Main(字符串[]args)
{
列表日期=新列表();
日期。添加(新日期时间(2014年1月1日);
添加(新的日期时间(2014年1月2日));
添加(新的日期时间(2014年1月8日));
添加(新的日期时间(2014年1月10日));
添加(新的日期时间(2014年1月11日));
添加(新日期时间(2014年1月12日));
var值=
日期。选择(dt=>newdaterange(dt,dt))
.Distinct(新日期连续比较()).ToArray();
foreach(值中的var范围)
{
控制台写入线(范围);
}
Console.ReadKey();
}
}
公共类日期范围
{
公共日期时间结束{get;set;}
公共日期时间开始{get;set;}
公共日期范围(日期时间结束,日期时间开始)
{
结束=结束;
开始=开始;
}
公共重写字符串ToString()
{
如果(开始==结束)
返回“[”+Start.ToString(“MM/dd/yyyy”)+“]”;
返回“[”+Start.ToString(“MM/dd/yyyy”)+”,“+End.ToString(“MM/dd/yyyy”)+””;
}
公共覆盖int GetHashCode()
{
返回Tuple.Create(Start,End).GetHashCode();
}
}
公共类DateConcertiveComparer:IEqualityComparer
{
公共布尔等于(日期范围x,日期范围y)
{
如果(x.End.AddDays(1)==y.Start)
{
x、 结束=y.结束;
返回true;
}
否则,如果(y.End.ADDDDAYS(1)==