首先,我是第五周在铁厂学习Java后端工程的学生。该课程由大约60%的Java、25%的JavaScript和15%的Clojure组成。
我被告知以下问题(在评论中概述):
;; Given an ArrayList of words, return a HashMap> containing a keys for every
;; word's first letter. The value for the key will be an ArrayList of all
;; words in the list that start with that letter. An empty string has no first
;; letter so don't add a key for it.
(defn index-words [word-list]
(loop [word (first word-list)
index {}]
(if (contains? index (subs word 0 1))
(assoc index (subs word 0 1) (let [words (index (subs word 0 1))
word word]
(conj words word)))
(assoc index (subs word 0 1) (conj nil word)))
(if (empty? word-list)
index
(recur (rest word-list) index))))我在使用zipmap时遇到了一个类似的问题,但我确信我错过了这个问题。代码编译,但无法运行。
具体来说,我未能更新'if‘的false子句中的hashmap索引。
我已经在REPL中测试了这个函数的所有组件,并且它们是独立工作的。但我很难把它们都放在一起。
供您参考,下面是调用word-list的代码。
(let [word-list ["aardvark" "apple" "zamboni" "phone"]]
(printf "index-words(%s) -> %s\n" word-list (index-words word-list)))与其从社区中得到一个有效的解决方案,我还希望能有几个指点让我的大脑朝着正确的方向移动。
发布于 2016-09-03 15:07:41
函数assoc不修改index。您需要处理assoc返回的新值。conj也是如此:它不会修改传递给它的映射。
我希望,这个答案是你期待得到的:只是一个指针,你的问题所在。
顺便说一句:如果您可以使用PersistentList,那么在使用reduce而不是loop和recur时,这就变成了一个一行。对您来说,一个有趣的函数可能是update-in。
和Clojure玩得开心。
发布于 2016-09-05 09:49:50
group-by函数可以满足您的需要。
first作为它的判别函数参数。它返回字符串的第一个字符,如果没有字符串,则返回nil:(first word)比(subs word 0 1)简单。dissoc删除键nil的条目。您很少需要在clojure中使用显式的loop。大多数常见的控制模式都是在像group-by这样的函数中捕获的。这些函数具有函数和可能的集合参数。最常见的例子是map和reduce。Clojure备忘单是对它们最有用的指南。
https://stackoverflow.com/questions/39307670
复制相似问题