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

使用F#match提取一周中的两天,f#,f#-3.0,F#,F# 3.0,我正在学习使用F#,我正在努力熟悉匹配表达式。我希望下面的代码能够从一周中选择连续两天,即当天和后天。它只选择当前日期。我错过了什么 DayOfWeek数组: let days = [|DayOfWeek.Sunday, true; DayOfWeek.Monday, false; DayOfWeek.Tuesday, true; DayOfWeek.Wednesday, true; D

我正在学习使用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
                | _ -> ()
            |_ -> ()
        ]

我觉得您的解决方案非常复杂,就像其他人提到的,只有当明天的DayOfWeek的基本int值大于今天的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]
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"

我觉得您的解决方案非常复杂,就像其他人提到的,只有当明天的DayOfWeek的基本int值大于今天的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]
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"

我认为通过使用F#/.net的枚举上限,您可以更轻松地编写此代码:


我认为通过使用F#/.net的枚举上限,您可以更轻松地编写此代码:


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

这里是我将如何做到这一点,不允许你采取任何数量的天,而不仅仅是两天

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
好吧,我不打算把这本书的功能印出来,你只需要运用你的想象力就行了

我希望这有帮助


编辑我让它处理无限多天。

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

这里是我将如何做到这一点,不允许你采取任何数量的天,而不仅仅是两天

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
好吧,我不打算把这本书的功能印出来,你只需要运用你的想象力就行了

我希望这有帮助


编辑我让它处理无限多天。

提示:这在星期五有效,但不是星期六。@Mattephenson更具体地说,除了包含星期六的元组外,对于每个为真的元组,这将返回两天。否,我认为@MattStephenson意味着你的逻辑只适用于周六前一天,因为(int DayOfWeek.Saturday)是6,这是最大值。@kimsk是的,但这只适用于今天,因为今天是周六,我错了吗?如果curDate等于星期四,我不是会回到星期四和星期五吗?是的,如果今天是星期四或星期天和星期一以外的任何一天,您的逻辑将返回两天。提示:这在星期五有效,但不是星期六。@mattenson更具体地说,你会说除了包含星期六的元组之外,每个元组都会返回两天吗?不,我认为@MattStephenson意味着你的逻辑只适用于星期六前一天,因为(int DayOfWeek.Saturday)是6,它是最大值。@kimsk是的,但这只适用于今天,因为今天是星期六,我错了吗?如果curDate等于星期四,我会返回星期四和星期五吗?是的,如果今天是星期四或星期天和星期一以外的任何一天,您的逻辑将返回两天。您忘记了匹配表达式中的|字符作为dayAfter函数。更重要的是,通过省略默认情况(例如,
| |->failwith“invalid day of week”
),您可能会收到“模式匹配不完整”警告。您忘记了dayAfter函数的匹配表达式中的|字符。更重要的是,也许通过省略默认情况(例如,
|->failwith“invalid day of week”
),您将得到“模式匹配不完整”警告。
DayOfWeek.Sunday
|> next 10000 days
|> Seq.iter (printfn "%A")