2014-10-12 110 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))