我有一份日期清单:
DateTime(2016, 03, 01),
DateTime(2016, 04, 01),
DateTime(2016, 05, 01)
现在给定一个日期,一个“StartDate”。在startdate和之前的最后一个日期之后创建日期列表的最简单方法是什么?
即。 - 如果我提供日期DateTime(2016,03,15),我需要返回
{{1}}
它可以像查找最后一个“活动”日期一样简单,然后只使用该日期的位置。但我不确定如何做到这一点而不会让它变得非常复杂。
答案 0 :(得分:2)
如果您的列表已经排序,则可以使用二进制搜索:
var index = dates.BinarySearch(start);
// If the precise value isn't found, index will be the bitwise complement
// of the first index *later* than the target, so we need to subtract 1.
// But if there were no values earlier, we should start from 0.
if (index < 0)
{
index = Math.Max(~index - 1, 0);
}
return dates.Skip(index).ToList();
这假定日期是唯一的。如果有多个日期与start
相同,则无法保证会找到第一个日期。如果这是一个问题,你需要向后搜索,直到找到第一场比赛。
您尚未指定是否存在完全匹配,您是否要在此之前包含日期。如果你这样做,你需要调整一下这段代码。
答案 1 :(得分:1)
var partialResult = dates.Where(x => x >= date).ToList();
partialResult.Add(dates.Where(x => x < date).Max());
IList<DateTime> result = partialResult.OrderBy(x => x).ToList();
答案 2 :(得分:1)
不要让它变得复杂,如果我正确理解你的要求。您需要 StartDate 之后的所有日期以及第一次匹配之前的最后一个条目( If Any )。然后我发现这是最简单易读的方式:
var results = dates.FindAll(x => x >= StartDate);
int index = dates.FindLastIndex(x => x < StartDate);
// there might be no match, if all the list is resulted
if (index >= 0)
results.Insert(0, dates[index]);
如果您更喜欢一种查询样式,可以执行以下操作(我发现它不可读):
var results = dates.Where(x => x >= StartDate)
.Concat(dates.Where(x => x < StartDate)
.OrderByDescending(x => x).Take(1));
如果你喜欢花哨的方式,最后的选择:
int startIndex = dates.FindLastIndex(x=> x < StartDate);
startIndex = Math.Max(0, startIndex);
var results = dates.Skip(startIndex).ToList();