在 F# 中合并两个列表
Merging two lists in F#
我编写了这个将两个列表合并在一起的函数,但由于我对函数式编程还很陌生,所以我想知道是否有更好(更简单)的方法来做到这一点?
let a = ["a"; "b"; "c"]
let b = ["d"; "b"; "a"]
let merge a b =
// take all a and add b
List.fold (fun acc elem ->
let alreadyContains = acc |> List.exists (fun item -> item = elem)
if alreadyContains = true then
acc
else
elem :: acc |> List.rev
) b a
let test = merge a b
预期结果是:["a"; "b"; "c"; "d"],我正在还原列表以保持原始顺序。我以为我可以使用 List.foldBack(并删除 List.rev)实现相同的效果,但它会导致错误:
类型不匹配。期待一个
'a
但给出了
'一个列表
当统一 ''a' 和 ''a list'
时,结果类型将是无限的
为什么使用foldBack时有区别?
你可以使用类似下面的东西
let merge a b =
a @ b
|> Seq.distinct
|> List.ofSeq
请注意,这将保留顺序并删除所有重复项。
在 F# 4.0 中,这将被简化为
let merge a b = a @ b |> List.distinct
如果我想以类似于您的原始版本(使用 fold
)的方式编写此代码,那么我要做的主要更改是将 List.rev
移到函数之外(每次添加新元素时都会调用 List.rev
,如果添加偶数个元素,这是错误的!)
因此,与您的解决方案非常相似的解决方案是:
let merge a b =
(b, a)
||> List.fold (fun acc elem ->
let alreadyContains = acc |> List.exists (fun item -> item = elem)
if alreadyContains = true then acc
else elem :: acc)
|> List.rev
这里使用双管道运算符||>
将两个参数传递给fold
函数(这不是必需的,但我觉得这样更好一点),然后将结果传递给List.rev
.
我编写了这个将两个列表合并在一起的函数,但由于我对函数式编程还很陌生,所以我想知道是否有更好(更简单)的方法来做到这一点?
let a = ["a"; "b"; "c"]
let b = ["d"; "b"; "a"]
let merge a b =
// take all a and add b
List.fold (fun acc elem ->
let alreadyContains = acc |> List.exists (fun item -> item = elem)
if alreadyContains = true then
acc
else
elem :: acc |> List.rev
) b a
let test = merge a b
预期结果是:["a"; "b"; "c"; "d"],我正在还原列表以保持原始顺序。我以为我可以使用 List.foldBack(并删除 List.rev)实现相同的效果,但它会导致错误:
类型不匹配。期待一个
'a
但给出了
'一个列表
当统一 ''a' 和 ''a list'
为什么使用foldBack时有区别?
你可以使用类似下面的东西
let merge a b =
a @ b
|> Seq.distinct
|> List.ofSeq
请注意,这将保留顺序并删除所有重复项。
在 F# 4.0 中,这将被简化为
let merge a b = a @ b |> List.distinct
如果我想以类似于您的原始版本(使用 fold
)的方式编写此代码,那么我要做的主要更改是将 List.rev
移到函数之外(每次添加新元素时都会调用 List.rev
,如果添加偶数个元素,这是错误的!)
因此,与您的解决方案非常相似的解决方案是:
let merge a b =
(b, a)
||> List.fold (fun acc elem ->
let alreadyContains = acc |> List.exists (fun item -> item = elem)
if alreadyContains = true then acc
else elem :: acc)
|> List.rev
这里使用双管道运算符||>
将两个参数传递给fold
函数(这不是必需的,但我觉得这样更好一点),然后将结果传递给List.rev
.