2012-10-24 91 views
4

我試圖編寫一個函數去除Clojure中的所有ASCII元音。我對Clojure很陌生,並且對字符串有點麻煩。例如,字符串"hello world"將返回"hll wrld"。我感謝幫助!clojure中的剝離元音

回答

15

您可以利用字符串類的基礎功能。

user=> (.replaceAll "hello world" "[aeiou]" "")   
"hll wrld" 

如果感覺就像作弊,你可以把該字符串轉換成一個序列,然後用一組的補過濾,然後把那回字符串。

user=> (apply str (filter (complement #{\a \e \i \o \u}) (seq "hello world"))) 
"hll wrld" 

clojure中的集合也是函數。 complement接受一個函數並返回一個函數,該函數返回原始函數的邏輯非。這相當於這個。 apply需要一個函數和一堆參數,並用這些參數調用函數(粗略地說)。

user=> (apply str (filter #(not (#{\a \e \i \o \u} %)) (seq "hello world"))) 
"hll wrld" 

編輯

一個更多...

user=> (apply str (re-seq #"[^aeiou]" "hello world")) 
"hll wrld" 

#"[^aeiou]"是一個正則表達式,並重新打開序列比賽成起。它像clojure一樣,似乎表現良好。在下降到Java之前,我可能會嘗試這個。 seq字符串的速度比較慢。

重要編輯

還有另一種方式,那就是用clojure.string/replace。鑑於它可以在Clojure或Clojurescript中工作,這可能是最好的方式。

例如

dev:cljs.user=> (require '[clojure.string :as str]) 
nil 

dev:cljs.user=> (str/replace "hello world" #"[aeiou]" "") 
"hll wrld" 
+0

非常有幫助,非常感謝你 –

+0

@JoeCrawley感謝您接受答案。我剛剛添加了一個,可能是最好的。祝你好運! – Bill

+5

'還有'(remove pred ...)'(filter(補償pred)...)'。你不必在字符串上調用'seq'。序列函數以您的名義完成。 – kotarak

8

比爾是大多數是正確的,但錯誤的,足以保證這個答案,我認爲。

user=> (.replaceAll "hello world" "[aeiou]" "")   
"hll wrld" 

該解決方案完全可以接受。事實上,這是最好的解決方案。如果解決方案是最乾淨和最快的解決方案,那麼下降到Java沒有任何問題。

另一種解決方案就像他說的那樣使用序列函數。但是,他的代碼有點奇怪。切勿使用filter(not ..)complement。還有一個功能,專爲,remove

user> (apply str (remove #{\a \e \i \o \u} "hello world")) 
"hll wrld" 

你也不必調用seq的字符串。所有Clojure的seq函數都會爲你處理。

他最後的解決方案很有趣,但我更喜歡第一個,因爲它不涉及(apply str ..)

+1

我喜歡刪除的例子。謝謝! – Bill

+0

另外,String/replaceAll的缺點是它每次都會創建一個新的Pattern對象。儘管如此,它的速度仍然比塞慶快。 – Bill

+0

@ Bill還有一個替換匹配器的版本。你可以做到這一點,而不是每次都創建一個模式對象。 – Rayne