Search code examples
clojurehashmapzipmap

building a hashmap from an array in clojure


First off, I am a student in week 5 of 12 at The Iron Yard studying Java backend engineering. The course is composed of roughly 60% Java, 25% JavaScript and 15% Clojure.

I have been given the following problem (outlined in the comment):

;; 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))))

I was able to get a similar problem working using zipmap but I am positive that I am missing something with this one. The code compiles but fails to run.

Specifically, I am failing to update my hashmap index in the false clause of the 'if'.

I have tested all of the components of this function in the REPL, and they work in isolation. but I am struggling to put them all together.

For your reference, here is the code that calls word-list.

  (let [word-list ["aardvark" "apple" "zamboni" "phone"]]
    (printf "index-words(%s) -> %s\n" word-list (index-words word-list)))

Rather than getting a working solution from the community, my hope is for a few pointers to get my brain moving in the right direction.


Solution

  • The function assoc does not modify index. You need to work with the new value that assoc returns. Same is true for conj: it does not modify the map you pass it.

    I hope, this answer is of the nature you expected to get: just a pointer where your problem is.

    BTW: If you can do with a PersistentList this becomes a one-liner when using reduce instead of loop and recur. An interesting function for you could be update-in.

    Have fun with Clojure.