Создание hashmap из массива в ближайшем будущем

Во-первых, я учусь на неделе 5 из 12 в The Iron Yard и изучаю бэкэнд-инжиниринг 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 но я уверен, что что-то упустил с этим. Код компилируется, но не запускается.

В частности, я не могу обновить свой индекс хэш-карты в ложном предложении "если".

Я проверил все компоненты этой функции в REPL, и они работают изолированно. но я изо всех сил пытаюсь собрать их всех вместе.

Для справки, вот код, который вызывает список слов.

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

Вместо того, чтобы получить рабочее решение от сообщества, я надеюсь, что несколько указателей заставят мой мозг двигаться в правильном направлении.

2 ответа

Решение

Функция assoc не модифицирует index, Вам нужно работать с новым значением, которое assoc возвращается. То же самое верно для conj: это не изменяет карту, которую вы передаете.

Я надеюсь, что этот ответ имеет характер, который вы ожидали получить: просто указатель, где ваша проблема.

Кстати, если вы можете сделать с PersistentList это становится однострочным при использовании reduce вместо loop а также recur, Интересная функция для вас может быть update-in,

Веселитесь с Clojure.

group-by Функция делает то, что вам нужно.

  • Ты можешь использовать first в качестве аргумента его отличительной функции. Возвращает первый символ строки или nil если его нет: (first word) проще чем (subs word 0 1),
  • использование dissoc удалить запись для ключа nil,

Вам редко нужно использовать явное loop в ближайшем будущем. Наиболее распространенные шаблоны управления были зафиксированы в таких функциях, как group-by, Такие функции имеют функцию и, возможно, аргументы коллекции. Самые распространенные примеры map а также reduce, Шпаргалка Clojure является наиболее полезным руководством для них.

Другие вопросы по тегам