假设我有一些像这样的代码:如何在OCAML中使用List.Map跳过一个术语?
List.map (fun e -> if (e <> 1) then e + 1 else (*add nothing to the list*))
有没有办法做到这一点?如果是这样,怎么样?
我想同时操作该项目,如果它符合一些标准,并忽略它,如果它不。因此List.filter似乎不是解决方案。
假设我有一些像这样的代码:如何在OCAML中使用List.Map跳过一个术语?
List.map (fun e -> if (e <> 1) then e + 1 else (*add nothing to the list*))
有没有办法做到这一点?如果是这样,怎么样?
我想同时操作该项目,如果它符合一些标准,并忽略它,如果它不。因此List.filter似乎不是解决方案。
SML有一个函数mapPartial,它正是这样做的。可悲的是,这个功能在OCaml中不存在。但是你可以自己简单地定义它是这样的:
let map_partial f xs =
let prepend_option x xs = match x with
| None -> xs
| Some x -> x :: xs in
List.rev (List.fold_left (fun acc x -> prepend_option (f x) acc) [] xs)
用法:
map_partial (fun x -> if x <> 1 then Some (x+1) else None) [0;1;2;3]
将返回[1;3;4]
。
或者您可以使用filter_map
from extlib ygrek指出。
另外,您可以过滤列表,然后应用所得到的名单上图如下:
let map_bis predicate map_function lst =
List.map map_function (List.filter predicate lst);;
# val map_bis : ('a -> bool) -> ('a -> 'b) -> 'a list -> 'b list = <fun>
用法:
# map_bis (fun e -> e<>1) (fun e -> e+1) [0;1;2;3];;
- : int list = [1; 3; 4]
另一个解决方案是直接使用foldl
:
let f e l = if (e <> 1)
then (e + 1)::l
else l
in List.fold_left f [] list
但我的偏好是filter_map
作为迈克尔·
,如果你想保持他们或空列表,您也可以映射值独居名单如果你不这样做,然后连接结果。
List.concat (List.map (fun e -> if (e <> 1) then [e + 1] else []) my_list)
list.filter_map in extlib – ygrek 2010-07-08 11:43:49