我正在嘗試做相當簡單的事情。我想要一個字符串,如「1,000」,並返回字符串「1000」。OCaml中的空字符
這裏是我的嘗試:
String.map (function x -> if x = ',' then '' else x) "1,000";;
但是我得到一個編譯錯誤說有一個語法錯誤WRT ''
感謝您的見解!
我正在嘗試做相當簡單的事情。我想要一個字符串,如「1,000」,並返回字符串「1000」。OCaml中的空字符
這裏是我的嘗試:
String.map (function x -> if x = ',' then '' else x) "1,000";;
但是我得到一個編譯錯誤說有一個語法錯誤WRT ''
感謝您的見解!
什麼你需要在這裏就像下面,不幸的是沒有在標準庫中的函數:
(* 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中相當昂貴。)
不幸的是,沒有像你要找的人物。有一個長度爲0個字符的字符串(""
),但沒有任何字符不存在。所有角色(可以這麼說)都是1個字符。
要解決您的問題,您需要比String.map
更爲一般的操作。地圖的本質是它的輸入和輸出具有相同的形狀但內容不同。對於字符串,這意味着輸入和輸出是相同長度的字符串。除非你真的想要避免強制性編碼(這實際上是一個很好的避免,尤其是當開始使用OCaml時),你最好使用String.iter
和緩衝區(來自Buffer
模塊)。
更新
由Andreas Rossberg給出的string_map_partial
功能是相當不錯的。下面是一個使用String.iter
另一種實現方式和緩衝區:
let string_map_partial f s =
let b = Buffer.create (String.length s) in
let addperhaps c =
match f c with
| None ->()
| Some c' -> Buffer.add_char b c'
in
String.iter addperhaps s;
Buffer.contents b
只是一個替代實現與不同風格的權衡。不會更快,也可能不會更慢。它仍然是寫入命令(出於同樣的原因)。