f# - F# 在没有第一个或最后一个元素的情况下优雅地折叠?
问题描述
假设您有一个字符串列表: [ "a"; “乙”;"c" ] 并且您想将其转换为单个字符串,如下所示: "a,b,c" 请注意缺少最后一个逗号。我发现这种情况一次又一次地出现在我身上,想想所有不允许尾随逗号出现的编程语言,你正在构建某种代码生成器。我通常会得到类似的结果:
let listOfThings = ["a";"b";"c"]
let folded =
listOfThings
|> List.map (fun i -> i + ",")
|> List.fold (+) ""
|> (fun s -> s.Substring(0, s.Length - 1))
我觉得已经有一些类似折叠的功能,因为这似乎是一个基本的用例,我只是不知道它的名字是什么,或者用什么名字来搜索它。
解决方案
Afold
递归地将折叠函数应用于列表的所有值,从初始状态开始,在这种情况下您并不特别想要。
使用使用列表的头部作为其起始状态的 reduce 更简单:
listOfThings |> List.reduce (fun sum cur -> sum + "," + cur) // "a,b,c"
一个小缺点是,由于它使用列表头,因此使用空列表调用 reduce 会失败。您可以通过检查空列表来缓解这种情况。
正如您所描述的,没有任何内置函数,我们跳过为最后一个元素添加尾随逗号:
let rec join = function
| [] -> ""
| [x] -> x
| x::xs -> x + "," + join xs
["a"; "b"; "c"] |> join // a,b,c
但是,最有效的方法是使用String.Join
which 内部使用 a StringBuilder
,而reduce
为每次调用分配一个新字符串:
String.Join(",", listOfThings) // "a,b,c"