OCaml中的空字符

时间:2014-01-07 03:25:19

标签: ocaml

我正在尝试做一些相当简单的事情。我想取一个字符串,如“1000”,并返回字符串“1000”。

这是我的尝试:

String.map (function x -> if x = ',' then '' else x) "1,000";; 

但是我收到编译错误,说有''

语法错误

感谢您的见解!

3 个答案:

答案 0 :(得分:5)

不幸的是,没有像你正在寻找的那个角色。有一个长度为0个字符的字符串(""),但没有任何字符根本不存在。所有字符(可以这么说)都是1个字符。

要解决您的问题,您需要比String.map更通用的操作。地图的本质是它的输入和输出具有相同的形状但内容不同。对于字符串,这意味着输入和输出是相同长度的字符串。

除非你真的想避免命令式编码(这实际上是一件很好的事情要避免,特别是在开始使用OCaml时),你最好使用String.iter和缓冲区(来自{{1}) }模块)。

<强>更新

Andreas Rossberg给出的Buffer函数非常好。这是另一个使用string_map_partial和缓冲区的实现:

String.iter

只是一种具有不同风格权衡的替代实现。不快,也可能不慢。它仍然是强制性的(出于同样的原因)。

答案 1 :(得分:4)

这里你需要的是一个类似下面的函数,遗憾的是它不在标准库中:

(* string_map_partial : (char -> char option) -> string -> string *)
let string_map_partial f s =
  let buf = String.create (String.length s) in
  let j = ref 0 in
  for i = 0 to String.length s - 1 do
    match f s.[i] with
    | None -> ()
    | Some c -> buf.[!j] <- c; incr j
  done;
  String.sub buf 0 !j

然后你可以写:

string_map_partial (fun c -> if c = ',' then None else Some c) "1,000"

(注意:我为string_map_partial选择了一个命令式实现,因为纯函数式实现需要重复的字符串连接,这在OCaml中相当昂贵。)

答案 2 :(得分:0)

纯功能版本可能是这个:

let string_map_partial f s =
      let n = String.length s in
      let rec map_str i acc =
          if i < n then 
              map_str (i + 1) (acc ^ (f (String.make 1 s.[i])))
          else acc 
      in map_str 0 ""

这是终端递归,但性能不如命令式版本。