使用F#匹配提取一周中的两天

时间:2014-09-14 00:26:58

标签: f# f#-3.0

学习使用F#,我试图熟悉匹配表达式。我希望下面的代码可以在本周,当天和第二天连续两天选择。它只挑选当天。我在这里缺少什么?

DayOfWeek数组:

let days = [|DayOfWeek.Sunday, true; 
             DayOfWeek.Monday, false; 
             DayOfWeek.Tuesday, true;
             DayOfWeek.Wednesday, true; 
             DayOfWeek.Thursday, true; 
             DayOfWeek.Friday, true; 
             DayOfWeek.Saturday, true;|]

匹配表达式:

 let curDate = DateTime.Now
 let validDates = 
        [
            for i in days do
            match i with
            | day, true ->
                match day with
                | x when int x = int curDate.DayOfWeek || 
                    int x > int curDate.DayOfWeek
                    && int x - int curDate.DayOfWeek = 1 ->
                    yield
                        x
                | _ -> ()
            |_ -> ()
        ]

3 个答案:

答案 0 :(得分:3)

你的解决方案对我来说似乎非常复杂,并且像其他人一样提到它只有在明天的DayOfWeek的基础int值比今天更大的情况下才有效。如你所知,这周是一个循环,因此逻辑不会总是成立。我不想吃勺,但有一个更简单的解决方案:

let today = DateTime.Now.DayOfWeek

let days = [|DayOfWeek.Sunday, true; 
             DayOfWeek.Monday, false; 
             DayOfWeek.Tuesday, true;
             DayOfWeek.Wednesday, true; 
             DayOfWeek.Thursday, true; 
             DayOfWeek.Friday, true; 
             DayOfWeek.Saturday, true;|]

let today_and_tomorrow =
    let idx_today = Array.findIndex (fun (day, _) -> day = today) days
    days.[idx_today], days.[idx_today + 1 % days.Length]

答案 1 :(得分:1)

我认为你可以通过使用F#/。net:

的枚举上限来更容易地写出来。
open System;;

let weekdayAfter (day : DateTime) : DayOfWeek = 
    int day.DayOfWeek
    |> (fun i -> (i+1) % 7) 
    |> Microsoft.FSharp.Core.LanguagePrimitives.EnumOfValue<_, _>                 

let today_and_tomorrow = 
   let today = DateTime.Today
   (today.DayOfWeek, weekdayAfter today)

如果你真的想使用模式匹配,那么为什么不选择可读/明显的解决方案:

let dayAfter (day : DateTime) =
    match day.DayOfWeek with
    | DayOfWeek.Sunday    -> DayOfWeek.Monday
    | DayOfWeek.Monday    -> DayOfWeek.Tuesday
    | DayOfWeek.Tuesday   -> DayOfWeek.Wednesday
    | DayOfWeek.Wednesday -> DayOfWeek.Thursday
    | DayOfWeek.Thursday  -> DayOfWeek.Friday
    | DayOfWeek.Friday    -> DayOfWeek.Saturday
    | DayOfWeek.Saturday  -> DayOfWeek.Sunday
    | _                   -> failwith "should never happen"

答案 2 :(得分:1)

对我来说,困难在于使用模式匹配。

以下是我如何做到这一点,允许你花费任意天数,而不仅仅是两天。

open System

let next count days day =
    seq { while true do yield! days } // make the days array infinite
    |> Seq.skipWhile (fun (d, _) -> d <> day) // skip until we find our day
    |> Seq.filter (fun (_, incl) -> incl) // get rid of 'false' days
    |> Seq.take count // take the next 'count' of days
    |> Seq.map (fun (d, _) -> d) // we only care about the day now, so a simple map gets rid of the boolean

使用您的天数,我得到以下内容:

DayOfWeek.Sunday
|> next 2 days

val it : seq<DayOfWeek> = seq [Sunday; Tuesday]

DayOfWeek.Thursday
|> next 3 days

val it : seq<DayOfWeek> = seq [Thursday; Friday; Saturday]

DayOfWeek.Sunday
|> next 10000 days
|> Seq.iter (printfn "%A")

好吧,我不会打印这个人的作品,你只需要用你的想象力。 :)

我希望有所帮助!

编辑我让它处理了无数天。