2

首先,我是 The Iron Yard 12 周第 5 周的学生,学习 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)))

与其从社区获得可行的解决方案,我希望得到一些指导,让我的大脑朝着正确的方向前进。

4

2 回答 2

5

该功能assoc不修改index。您需要使用assoc返回的新值。也是如此conj:它不会修改您传递的地图。

我希望,这个答案是你期望得到的性质:只是你的问题所在的一个指针。

顺便说一句:如果您可以使用 a代替and ,PersistentList则 this 将成为单线。对您来说一个有趣的功能可能是.reducelooprecurupdate-in

用 Clojure 玩得开心。

于 2016-09-03T15:07:41.857 回答
0

group-by功能可以满足您的要求。

  • 您可以将first其用作判别函数参数。它返回字符串的第一个字符,或者nil如果没有: (first word)(subs word 0 1).
  • 用于dissoc删除 key 的条目nil

您很少需要loop在 clojure 中使用显式 s。最常见的控制模式已在诸如group-by. 此类函数具有函数和可能的集合参数。最常见的例子是mapreduceClojure 备忘单是最有用的指南。

于 2016-09-05T09:49:50.990 回答