ответ Стюарта это хорошо, но я не могу не думать Вы знаете, начинайте с нескончаемой последовательности лет с этим конкретным месяцем/днем и позвольте собеседнику определить, сколько взять или добавить собственный фильтр.
На этом этапе вы должны думать об «безумном поручении». :) Первая проблема, с которой я столкнулся - потому что мой второй неудачный тест не удался - было то, что вы не можете весело наращивать DateTime
навсегда, поэтому вам нужно написать код, чтобы ограничить это.
Так что я в конечном итоге с гораздо более кода, чем меньше, из-за борьбы с капризами реальных данных:
// All instances of this specified month/day beginning with 'start'.
let myDate (dw:System.DayOfWeek) (start:System.DateTime) =
// Start with a sequence of one date for each year...
seq {
// Don't run the date past DateTime.MaxValue, there lurks an
// ArgumentOutOfRangeException. Comparison also must be on the
// valid side of DateTime.MaxValue. Don't bother with try/with
// here in a sequence expression, you can't do that.
let maxDateBarrier = DateTime.MaxValue.AddYears(-1)
let mutable keepGoing, date = true, start
while keepGoing do
yield date
// if date.Year % 100 = 0 then printfn "%A" date.Year
if date <= maxDateBarrier then
date <- date.AddYears(1)
else
keepGoing <- false
}
|> Seq.where (fun date -> date.DayOfWeek = dw)
Немного многословным. Тест # 1 работает отлично:
let printDates (dates : DateTime seq) =
for date in dates do
printfn "%A" date.Year
// Take the next 5
myDate DayOfWeek.Sunday DateTime.Now
|> Seq.take 5
|> printDates
Тест # 2 фактически перебирает все из дат в моей последовательности:
// Take up to 5 before 2040.
// Note: this statement actually iterates through *all* the years in the
// sequence if you truncate to a length longer than Seq.where returns.
myDate DayOfWeek.Sunday (DateTime(2017, 2, 13))
|> Seq.where (fun date -> date.Year < 2040)
|> Seq.truncate 5
|> printDates
Является Тест # 2 причина, чтобы добавить endDate
функции myDate
? Нет, это скорее аргумент, чтобы лучше использовать последовательности. Используйте takeWhile
вместо where
:
// Try again: Take up to 5 before 2040.
// Terminate the sequence early with takeWhile.
myDate DayOfWeek.Sunday (DateTime(2017, 2, 13))
|> Seq.takeWhile (fun date -> date.Year < 2040)
|> Seq.truncate 5
|> printDates
Намного лучше. Пропустил мою цель «меньше кода», но я в порядке с этим. :)
Мы понимаем, что вы имеете в виду, но что вы пробовали и что вы сочтете сложным? Это не служба написания кода ... – scrwtp