如何获取列表的最后一个元素的值?我注意到List.hd(或.Head)返回一个项目,而List.tl(或.Tail)返回一个列表。
是否使用rev函数颠倒列表并获取hd是唯一的方法?谢谢。
试试这个函数。尽管函数使用了递归,但由于是尾递归,所以最终会被优化为迭代。无论如何,这个函数很可能比翻转整个列表(使用 List.rev
)更快。
let rec last = function
| hd :: [] -> hd
| hd :: tl -> last tl
| _ -> failwith "Empty list."
Pavel Minaev的答案绝对值得考虑。尽管如此,你所请求的算法在某些罕见情况下可能会有用,并且是完成任务最有效的方法。
一般来说,如果您需要这样做,那么您正在做错误的事情。由于F#列表是单向链接的,访问最后一个元素是代价高昂的 - O(N)
,其中N是list
的大小。尝试重写您的算法,以便始终访问第一个元素,而不是最后一个(这是O(1)
)。如果您无法这样做,很可能您在选择数据结构时选择了错误的list
。
一个快速且简单的方法是使用List.reduce。假设列表名称为ls
,
let lastElement ls = List.reduce (fun _ i -> i) ls
就效率而言,我同意Pavel的看法。
let lastItem = myList |> List.rev |> List.head
将 myList
列表传递给 List.rev
函数。然后使用 List.head
处理结果。
同意,获取list
的最后一个元素或其他“可枚举”的序列不够高效。话虽如此,在Seq
模块中已经存在这个函数,即Seq.last
。
module Seq = let last xs = Seq.reduce (fun _ x -> x) xs
- kaeferlet mylist = [1;2;3;4;5]
let lastValue = mylist.[mylist.Length - 1]
本质上是命令式的吗?是的,但不需要递归。
List.length
需要遍历列表,访问也是如此。基本上你必须遍历两次列表。 - John PalmerSystem.Collections.Generic.List<_>
,它们与F#列表不同,并具有不同的性能目标。 - John PalmerSum of [Array(xi) - Array(xi-5)] where i start at 5
所使用的代码是:
series |> Array.windowed 5
|> Array.fold (fun s x ->
(x |> Array.rev |> Array.head) - (x |> Array.head) + s) 0
|> float
我认为你可以直接写
list.[0..list.Length-1]
这是一个非常老的问题,但以防万一有人来到这里:
使用 FSharp 5,您可以执行 x.[^index],其中 index 将从数组/列表的末尾开始。
let a = [1;2;3;4;5;6;7;8;9]
a.[^0] is 9
a.[^1] is 8
etc
let reversedList = List.rev originalList
let tailItem = List.hd reversedList