F#列表中的倒数第二项

San*_*ine 1 f#

这是我最初的想法,在被召唤之前没有任何问题; 这到底有什么问题?

let SecLastItem myList=  
    List.rev myList
        |>printfn myList.[1]
Run Code Online (Sandbox Code Playgroud)

我该如何纠正这个问题?查找列表中倒数第二项的最佳方法是什么?

Seh*_*cht 6

printfn 期待一种格式 printfn "%A" arg

但还有更多,功能编程有利于不变性,所以List.rev返回一个新的列表而不修改mylist
所以打印myList中的第二项不会让第二项从头开始只是第二项(如果它存在,否则它会崩溃)

这就是说你应该将功能分开,并记录/打印"更好地重用和可组合性".

// trySecLastItem : 'a list -> 'a option
let trySecLastItem = List.rev >> List.tryItem 2

// usage
printfn "%d" (trySecLastItem someList) // ex Some 42 or None
Run Code Online (Sandbox Code Playgroud)

现在作为trySecLastItem返回选项你需要处理它(defaultArg例如使用)

// maybeSecLast : int option
let maybeSecLast = trySecLastItem someList
printfn "%d" (defaultArg maybeSecLast 42)
Run Code Online (Sandbox Code Playgroud)


hoc*_*cho 5

查找列表倒数第二个项目的最佳方法是什么?

如果您不想反转列表,您可以使用模式匹配并在列表不够长的“倒数第二个项目”时返回一个选项。像这样的东西。

let rec secondToLast ls = 
    match ls with 
    |   []              -> None
    |   h :: ht :: []   -> Some(h)
    |   h :: t          -> secondToLast t
Run Code Online (Sandbox Code Playgroud)

测试

printfn "%A" (secondToLast [1; 2; 3; 4])
Run Code Online (Sandbox Code Playgroud)