2011-05-02 2 views
0

У меня есть массив, содержащий даты без выходных (не обязательно рабочие дни). Теперь я хочу только одну дату в месяц и только с определенного дня. Если день не существует в массиве, в результирующем списке должен быть следующий существующий день.Фильтрация массива даты в f #

Например: С учетом массива: 1.2.2010, 2.2.2010, 5.2.2010, 6.2.2010, ..., 1.3.2010, 2.3.2010, ..., 1.4.2010, 4.4. 2010

Я хочу, чтобы все даты на 2 на каждый месяц

Результат: 2.2.2010, 2.3.2010, 4.4.2010

Как сделать это в F #? Пожалуйста, предоставьте обучающее и приятное решение, я пытаюсь изучить F #. Я знаю, как это сделать по-настоящему :)

Спасибо! : D

ответ

1

Вот одно из возможных решений:

// Your input list with dates 
let input = [DateTime.Now] 
// We want 2nd day or later 
let number = 2 

input 
    // First, create group of dates for every Year/Month 
    // (so that all days in specifc month are in a single group) 
    |> Seq.groupBy (fun dt -> dt.Year, dt.Month) 
    |> Seq.map (fun ((y, m), dates) -> 
    // We want only dates that are later (or equal to) this 'limit' 
    let limit = new DateTime(y, m, number) 
    // Remove dates before the limit and then select minimal date 
    dates |> Seq.filter (fun d -> d >= limit) |> Seq.min) 
1

Вот еще (при условии, отсортированный вход):

type DateTime = System.DateTime 

let filterDayOrFollowing day (input:DateTime[]) = 
    (input, ([], None)) 
    ||> Array.foldBack (fun date (acc, following:DateTime option) -> 
     if date.Day = day then date::acc, None 
     else match following with 
      | Some f when date.Year = f.Year 
         && date.Month = f.Month 
         && date.Day < day -> f::acc, None 
      | _ -> acc, Some date) 
    |> fst 

let expected = [ DateTime(2010, 2, 2) 
       DateTime(2010, 3, 2) 
       DateTime(2010, 4, 4) ] 

let actual = 
    [| DateTime(2010, 2, 1) 
     DateTime(2010, 2, 2) 
     DateTime(2010, 2, 5) 
     DateTime(2010, 2, 6) 
     DateTime(2010, 3, 1) 
     DateTime(2010, 3, 2) 
     DateTime(2010, 4, 1) 
     DateTime(2010, 4, 4) |] 
    |> filterDayOrFollowing 2 

actual = expected |> printfn "actual = expected: %b" 
Смежные вопросы