如何在OCAML中跳过带有List.Map的术语?

Ste*_*owe 10 ocaml

假设我有一些像这样的代码:

List.map (fun e -> if (e <> 1) then e + 1 else (*add nothing to the list*))
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?如果是这样,怎么样?

如果它符合某些条件,我想要操纵该项目,如果不匹配则忽略它.因此,List.filter似乎不是解决方案.

sep*_*p2k 13

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)
Run Code Online (Sandbox Code Playgroud)

用法:

map_partial (fun x -> if x <> 1 then Some (x+1) else None) [0;1;2;3]
Run Code Online (Sandbox Code Playgroud)

会回来的[1;3;4].

或者你可以像ygrek指出的那样使用filter_mapextlib.

  • extlib中的List.filter_map (6认同)

Mic*_*and 7

两个电池EXTLIB提供的等效mapPartial:它们的延伸List模块sprovide一个filter_map的类型的功能('a -> 'b option) -> 'a list -> 'b list,允许在地图功能,以选择项目以及.


Ben*_*kin 5

另一种解决方案是直接使用foldl:

let f e l = if (e <> 1) 
            then (e + 1)::l 
            else l
in List.fold_left f [] list  
Run Code Online (Sandbox Code Playgroud)

但我的偏好是filter_mapMichael E