2014-01-07 42 views
2

我正在嘗試做相當簡單的事情。我想要一個字符串,如「1,000」,並返回字符串「1000」。OCaml中的空字符

這裏是我的嘗試:

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

但是我得到一個編譯錯誤說有一個語法錯誤WRT ''

感謝您的見解!

回答

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中相當昂貴。)

5

不幸的是,沒有像你要找的人物。有一個長度爲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 

只是一個替代實現與不同風格的權衡。不會更快,也可能不會更慢。它仍然是寫入命令(出於同樣的原因)。