OCaml中是否有更符合语言风格的元组列表转整型列表方法?
将
(int * int) list转为int list的优雅实现 你当前手写的递归实现有个容易忽略的问题:因为每次都把元素追加到累加器头部,最终返回的列表顺序是反转的——比如传入[(1,2); (3,4)],你的函数会输出[4;3;2;1],和预期的[1;2;3;4]不符。
不用自己手写递归,OCaml标准库已经提供了能覆盖这个场景的高阶函数,下面是几种常用的写法:
用
List.fold_left实现:fold_left本身就是从左到右遍历列表、累积结果的操作,和你写的辅助递归函数逻辑完全等价,不需要自己写模式匹配:(* 直观写法,短列表场景足够用 *) let tuples_list_to_list l = List.fold_left (fun acc (a,b) -> acc @ [a;b]) [] l (* 尾递归优化版,适合超长列表,最后反转一次即可恢复顺序 *) let tuples_list_to_list l = List.fold_left (fun acc (a,b) -> b::a::acc) [] l |> List.rev最简洁的单行实现:用
List.concat_map。这个函数的作用就是对列表每个元素做转换(这里是把二元元组转成两元素的小列表),再把所有生成的小列表拼接成一个大列表,完全匹配你的需求:let tuples_list_to_list l = List.concat_map (fun (a,b) -> [a;b]) l这个写法语义最清晰,没有多余逻辑,输出顺序也完全符合预期。
补充说明:你之前尝试用List.map没成功是正常的——List.map只能把每个元组转成int list,最终得到的是int list list类型的嵌套列表,必须再做一次平铺拼接才能得到一维的int list,而List.concat_map就是把「map转换+concat拼接」两步合并成了一个函数。
内容的提问来源于stack exchange,提问作者VDS-Atomic
相关产品推荐
相关产品推荐

