Создание 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 является наиболее полезным руководством для них.