2014-10-12 88 views
0

我想用地圖中的文本替換地圖矢量中的某些字符。Clojure字符串替換爲帶有文本的地圖矢量

這應該是一個更大的程序的一部分,它包含文本列表中的所有單詞。

輸入向量是這樣的:

[{:text "bla. Bla! Blabla, foo"} 
    {:text "hello foo? bla Foo, blabla"} 
    {:text "bla blub Foo Bla blub"}] 

輸出應該是這樣的,並且應在價值排序:

{:bla 3 :Bla 2 :blub 2 :foo 2 :Foo 2 ... } 

但首先我想太乾淨一些字符串字符。

我地圖嘗試過,但我不明白爲什麼這個代碼不工作的權利:

(defn clean-texts [] 
    (map (fn [x] (clojure.string/replace x #"[.,]" "")) (:text texts))) 

整個代碼如下所示:

(ns keyword-finder.core 
    (:gen-class)) 

(def texts 
    [{:text "bla. Bla! Blabla, foo"} 
    {:text "hello foo? bla Foo, blabla"} 
    {:text "bla blub Foo Bla blub"}]) 

(defn clean-texts [] 
    (map (fn [x] (clojure.string/replace x #"[.,]" "")) (:text texts)) 
) 
+2

當構成約問題如果代碼不起作用,那麼如果你花時間描述你期望發生的事情,並且發生了什麼,那麼它將非常有幫助。 – Pointy 2014-10-12 13:59:10

+0

對不起我現在編輯 – Kingalione 2014-10-12 14:11:32

+0

你運行'clean-texts'得到了什麼結果?爲什麼它們不正確? – soulcheck 2014-10-12 14:20:52

回答

4

你需要的是這樣的:

(defn tokenize [s] 
    (-> s 
    (.replaceAll "[^a-zA-Z\\s]" "") 
    (clojure.string/split #" "))) 

這將刪除字符串中的所有非字母,因此當應用於「bla。blah,blah」時,它會給您「bla blah blah」

(defn word-counts [texts] 
    (let [tokens 
    (->> texts 
     (map (comp tokenize :text)) 
     (apply concat) 
     (map keyword))] 
    (frequencies tokens))) 

此函數從地圖中提取key:text的值,將tokenize應用於所有生成的字符串,將它們連接成單詞列表,將它們轉換爲關鍵字,最後使用內置函數返回關鍵字計數frequencies

(word-counts texts) 

產生{:BLA 3:布拉2:BLABLA 1:FOO 2:您好1:富2:布拉布拉1:泡殼2}

+0

是的,但正則表達式應該是「[a-zA-z] \\ s」。但仍然謝謝 – Kingalione 2014-10-12 15:31:00

+0

@Kingalione修復了它 – 2014-10-12 15:35:39

+0

並使它完美我怎樣才能按值排序,但仍然返回相同的結果?我必須寫一個自己的比較器嗎? – Kingalione 2014-10-12 15:36:06

3

你申請map到錯誤的序列:

(:text texts) 

回報nil因爲:text適用於整個texts列表。

什麼你可能想要做的是map整個texts名單上的內部函數,而對於每一個元素提取:text

(defn clean-texts [] 
    (map (fn [x] (clojure.string/replace (:text x) #"[.,]" "")) texts))