C# 破译连续日期范围的逻辑
假设我有一个班级,如下所示C# 破译连续日期范围的逻辑,c#,linq,logic,C#,Linq,Logic,假设我有一个班级,如下所示 public class Slots { //Other properties . . . public DateTime StartTime{get;set;} public DateTime EndTime{ge;set;} //Methods } 我有列表,确定连续慢组最有效的方法是什么? 连续插槽被定义为相对于前一个插槽在第二天开始的任何插槽组,没有重叠。 如果有一天的间隔(列表中没有该天的插槽),则应将
public class Slots
{
//Other properties
.
.
.
public DateTime StartTime{get;set;}
public DateTime EndTime{ge;set;}
//Methods
}
我有列表
,确定连续慢组最有效的方法是什么?
连续插槽被定义为相对于前一个插槽在第二天开始的任何插槽组,没有重叠。
如果有一天的间隔(列表中没有该天的插槽),则应将其视为另一个插槽组的开始
public List<List<Slots>> GetSlotGroups(List<SLots> slots)
{
//return list of slot groups according to logic described above
}
公共列表GetSlotGroup(列表插槽)
{
//根据上述逻辑返回插槽组列表
}
这是我想到的代码。我不知道它是否是最有效的,但它可读性强,速度也相当快
public static List<List<Slots>> GetGroups(List<Slots> slots)
{
List<List<Slots>> groups = new List<List<Slots>>();
DateTime? nextDate = null;
List<Slots> currentGroup = null;
foreach (var slot in slots.OrderBy(x => x.StartDate))
{
//first time through nextDate and currentGroup are null
//this condition matches the first time through or any time there is a gap in dates
if (nextDate == null || nextDate.Value < slot.StartDate)
{
if (currentGroup != null)
{
//if currentGroups isn't null then we have a completed group
groups.Add(currentGroup);
}
//start a new group
currentGroup = new List<Slots>();
}
nextDate = slot.EndDate.AddDays(1);
currentGroup.Add(slot);
}
//if there are no items in the collection currentGroup will still be null, otherwise currentGroup has the last group in it still. We finished iterating before finding a gap in dates
if (currentGroup != null)
{
groups.Add(currentGroup);
}
return groups;
}
公共静态列表GetGroups(列表槽)
{
列表组=新列表();
DateTime?nextDate=null;
List currentGroup=null;
foreach(slots.OrderBy(x=>x.StartDate)中的var插槽)
{
//第一次到下一个日期和当前组为空
//此条件与第一次到第二次或任何日期间隔时间相匹配
if(nextDate==null | | nextDate.Value
此代码通过将一个日期添加到上一个插槽的结束日期来跟踪范围内的下一个日期。当我们从一个插槽切换到另一个插槽时,我们附加到一个名为currentGroup的临时列表中。当我们的下一个日期小于当前插槽的开始日期时,我们将当前组添加到名为“组”的结果列表中,并为当前组创建一个新列表。最后,我们可能在currentGroup中为最后一个组添加了一些插槽,因此我们也必须添加该插槽。以下是我提出的代码。我不知道它是否是最有效的,但它可读性强,速度也相当快
public static List<List<Slots>> GetGroups(List<Slots> slots)
{
List<List<Slots>> groups = new List<List<Slots>>();
DateTime? nextDate = null;
List<Slots> currentGroup = null;
foreach (var slot in slots.OrderBy(x => x.StartDate))
{
//first time through nextDate and currentGroup are null
//this condition matches the first time through or any time there is a gap in dates
if (nextDate == null || nextDate.Value < slot.StartDate)
{
if (currentGroup != null)
{
//if currentGroups isn't null then we have a completed group
groups.Add(currentGroup);
}
//start a new group
currentGroup = new List<Slots>();
}
nextDate = slot.EndDate.AddDays(1);
currentGroup.Add(slot);
}
//if there are no items in the collection currentGroup will still be null, otherwise currentGroup has the last group in it still. We finished iterating before finding a gap in dates
if (currentGroup != null)
{
groups.Add(currentGroup);
}
return groups;
}
公共静态列表GetGroups(列表槽)
{
列表组=新列表();
DateTime?nextDate=null;
List currentGroup=null;
foreach(slots.OrderBy(x=>x.StartDate)中的var插槽)
{
//第一次到下一个日期和当前组为空
//此条件与第一次到第二次或任何日期间隔时间相匹配
if(nextDate==null | | nextDate.Value
此代码通过将一个日期添加到上一个插槽的结束日期来跟踪范围内的下一个日期。当我们从一个插槽切换到另一个插槽时,我们附加到一个名为currentGroup的临时列表中。当我们的下一个日期小于当前插槽的开始日期时,我们将当前组添加到名为“组”的结果列表中,并为当前组创建一个新列表。最后,我们假定currentGroup中有一些插槽用于最后一个组,因此我们还必须添加该插槽。这种操作最好使用GetEnumerator实现。 下面的代码要求对列表进行排序
IEnumerable<IEnumerable<Slot>> ToGroups(IEnumerable<Slot> slots)
{
using (var ie = slots.GetEnumerator())
{
var range = new List<Slot>();
while (ie.MoveNext())
{
if (range.Count > 0)
{
if (ie.Current.Start > range[range.Count - 1].End)
{
yield return range;
range = new List<Slot>{ie.Current};
continue;
}
}
range.Add(ie.Current);
}
yield return range;
}
}
IEnumerable到组(IEnumerable插槽)
{
使用(var ie=slots.GetEnumerator())
{
变量范围=新列表();
while(即MoveNext())
{
如果(range.Count>0)
{
如果(ie.Current.Start>range[range.Count-1].End)
{
收益率区间;
范围=新列表{ie.Current};
继续;
}
}
范围。添加(即当前);
}
收益率区间;
}
}
这种操作最好使用GetEnumerator实现。
下面的代码要求对列表进行排序
IEnumerable<IEnumerable<Slot>> ToGroups(IEnumerable<Slot> slots)
{
using (var ie = slots.GetEnumerator())
{
var range = new List<Slot>();
while (ie.MoveNext())
{
if (range.Count > 0)
{
if (ie.Current.Start > range[range.Count - 1].End)
{
yield return range;
range = new List<Slot>{ie.Current};
continue;
}
}
range.Add(ie.Current);
}
yield return range;
}
}
IEnumerable到组(IEnumerable插槽)
{
使用(var ie=slots.GetEnumerator())
{
变量范围=新列表();
while(即MoveNext())
{
如果(range.Count>0)
{
如果(ie.Current.Start>range[range.Count-1].End)
{
收益率区间;
范围=新列表{ie.Current};
继续;
}
}
范围。添加(即当前);
}
收益率区间;
}
}
这很简单。按StartTime
排序,然后在排序集上迭代,如果当前项与前一项不连续,则添加新组并使其成为当前项。然后只需将该项添加到当前组
public static List<List<Slots>> GetSlotGroups(List<Slots> slots)
{
var slotGroups = new List<List<Slots>>();
using (var e = slots.OrderBy(slot => slot.StartTime).GetEnumerator())
{
List<Slots> currentGroup = null;
Slots lastSlot = null;
while (e.MoveNext())
{
var currentSlot = e.Current;
if (lastSlot == null || currentSlot.StartTime.Date.Subtract(lastSlot.EndTime.Date).Days > 1)
slotGroups.Add(currentGroup = new List<Slots>());
currentGroup.Add(currentSlot);
lastSlot = currentSlot;
}
}
return slotGroups;
}
公共静态列表GetSlotGroup(列表插槽)
{
var slotGroups=新列表();
使用(var e=slots.OrderBy(slot=>slot.StartTime.GetEnumerator())
{
List currentGroup=null;
Slots lastSlot=null;
while(如MoveNext())
{
var currentSlot=e.电流;
如果(最后)