好的,所以在我的函数中添加一个数组,我保留一些东西来返回一个字符串作为键,列表作为值的哈希映射。我想只得到最终值并将其作为参数传递给另一个函数。
下面是我试图将其翻译成clojure的java代码
contents = documentContent.split("[ ,\\.]+");
for(int i = 0; i < contents.length; i++) {
String word = contents[i];
if(index.containsKey(word)) {
index.get(word).add(i);
} else {
List<Integer> list = new ArrayList<>();
list.add(i);
index.put(word, list);
}
}
Clojure代码到目前为止它有点工作,但我不能返回最终值并将其传递给另一个函数
(defn indexFinder [contents]
(let [mem (def xs (atom {}))]
(map-indexed
(fn [index element]
(if (contains? @xs element)
(swap! xs assoc element (conj (@xs element) index))
(swap! xs assoc element [index])))
contents)))
答案 0 :(得分:2)
以下是我的写作方式:
(defn index-finder [s]
(->> (clojure.string/split s #"[ ,\\.]+")
(map-indexed list)
(reduce (fn [acc [i w]]
(update acc w conj i)) {})))
使用示例:
(index-finder "aaa bbb ccc ddd aaa bbb") ;; {"aaa" (4 0), "bbb" (5 1), "ccc" (2), "ddd" (3)}
注意:在开始学习Clojure时,人们往往会认为他经常需要原子。
答案 1 :(得分:1)
我建议首先反对原子。
(->> (zipmap (range) contents) ;contents is a list of words
(reduce (fn [index [location word]]
(merge-with concat index {word (list location)})) {}))
示例:
user=> (def contents (clojure.string/split "hello there these are some words and some repeated words" #" "))
#'user/contents
user=> contents
["hello" "there" "these" "are" "some" "words" "and" "some" "repeated" "words"]
user=> (->> (zipmap (range) contents)
#_=> (reduce (fn [index [location word]]
#_=> (merge-with concat index {word (list location)})) {}))
{"hello" (0), "some" (7 4), "there" (1), "and" (6), "are" (3), "these" (2), "words" (9 5), "repeated" (8)}
答案 2 :(得分:1)
原始的indexFinder缺少一个强制其副作用(更新原子)的doall。并且还不需要声明mem。有了它,工作版本可能如下所示:
(defn indexFinder [contents]
(let [xs (atom {})]
(doall (map-indexed
(fn [index element]
(if (contains? @xs element)
(swap! xs assoc element (conj (@xs element) index))
(swap! xs assoc element [index])))
contents))
@xs))
您还可以简化地图索引部分:
(defn indexFinder [contents]
(let [xs (atom {})]
(doall (map-indexed
(fn [i e] (swap! xs update e conj i))
contents))
@xs))
或者如果你不想依赖副作用,你可以使用它(类似于Brandon的答案,但使用分组):
(defn index-finder [contents]
(->> (zipmap (range) contents)
(group-by last)
(fmap (partial map first))))
其中fmap用于映射函数值(参见algo.generic):
(defn fmap [f m]
(into (empty m) (for [[k v] m] [k (f v)])))