从 clojure 中的数组构建哈希图
building a hashmap from an array in clojure
首先,我是 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)))
与其从社区获得可行的解决方案,我更希望得到一些指导,让我的大脑朝着正确的方向前进。
函数assoc
不修改index
。您需要使用 assoc
returns 的新值。 conj
也是如此:它不会修改您传递给它的地图。
我希望,这个答案是您期望得到的答案:只是您问题所在的一个指针。
顺便说一句:如果你可以用 PersistentList
来做,那么当使用 reduce
而不是 loop
和 recur
时,这就变成了一行。对您来说,一个有趣的函数可能是 update-in
.
玩得开心 Clojure。
group-by
函数可以满足您的要求。
- 您可以使用
first
作为其判别函数参数。它
returns 字符串的第一个字符,如果没有则 nil
:
(first word)
比 (subs word 0 1)
. 更简单
- 使用
dissoc
删除键 nil
的条目。
你很少需要在 clojure 中使用明确的 loop
s。大多数常见的控制模式已在 group-by
等函数中捕获。这些函数具有函数和可能的集合参数。最常见的示例是 map
和 reduce
。 Clojure cheat sheet 是对他们最有用的指南。
首先,我是 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)))
与其从社区获得可行的解决方案,我更希望得到一些指导,让我的大脑朝着正确的方向前进。
函数assoc
不修改index
。您需要使用 assoc
returns 的新值。 conj
也是如此:它不会修改您传递给它的地图。
我希望,这个答案是您期望得到的答案:只是您问题所在的一个指针。
顺便说一句:如果你可以用 PersistentList
来做,那么当使用 reduce
而不是 loop
和 recur
时,这就变成了一行。对您来说,一个有趣的函数可能是 update-in
.
玩得开心 Clojure。
group-by
函数可以满足您的要求。
- 您可以使用
first
作为其判别函数参数。它 returns 字符串的第一个字符,如果没有则nil
:(first word)
比(subs word 0 1)
. 更简单
- 使用
dissoc
删除键nil
的条目。
你很少需要在 clojure 中使用明确的 loop
s。大多数常见的控制模式已在 group-by
等函数中捕获。这些函数具有函数和可能的集合参数。最常见的示例是 map
和 reduce
。 Clojure cheat sheet 是对他们最有用的指南。