代码之家  ›  专栏  ›  技术社区  ›  Steve Rowe

如何在OCAML中使用List.Map跳过术语?

  •  9
  • Steve Rowe  · 技术社区  · 16 年前

    假设我有这样的代码:

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

    有办法吗?如果是,怎么做?

    如果项目符合某些条件,我希望对其进行操作,如果不符合,则忽略它。因此,List.filter似乎不是解决方案。

    5 回复  |  直到 16 年前
        1
  •  14
  •   sepp2k    16 年前

    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

        2
  •  7
  •   Michael Ekstrand    16 年前

    两者 Batteries 和 Extlib 提供相当于 mapPartial :它们的扩展 List 模块提供a filter_map ('a -> 'b option) -> 'a list -> 'b list

        3
  •  5
  •   Benoît Fraikin    15 年前

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

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

    但我的偏好是 filter_map

        4
  •  4
  •   0xFF    16 年前

    或者,您可以过滤列表,然后在结果列表上应用映射,如下所示:

    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]
    
        5
  •  1
  •   rapha    15 年前

    如果希望保留值,也可以将值映射到单例列表;如果不想保留值,还可以将值映射到空列表,然后将结果合并。

    List.concat (List.map (fun e -> if (e <> 1) then [e + 1] else []) my_list)
    
        6
  •  0
  •   Valentyn Zakharenko    6 年前

    let rec process = function
      | 1 :: t -> process t
      | h :: t -> (h + 1) :: (process t)
      | []     -> []
    

    或尾部递归

    let process = 
      let rec f acc = function
        | 1 :: t -> f acc t
        | h :: t -> f ((h + 1) :: acc) t
        | []     -> List.rev acc in
      f []
    

    或者由标准函数组成

    let process l = 
      l |> List.filter ((<>)1)
        |> List.map ((+)1) 
    
    推荐文章