Второй случай терпит неудачу не потому, что форма if
возвращает неправильный тип значения, а потому, что карта содержит нечетное количество элементов. Литералы карты должны содержать четное количество форм, а if
— это одна форма.
Есть несколько способов добавить объекты на карты в Clojure.
Вы можете использовать conj
с вектором или аргумент карты:
(conj {:a :v} [:f :r]) ;;=> {:f :r, :a :v}
(conj {:a :v} {:f :r}) ;;=> {:f :r, :a :v}
Вы можете использовать assoc
с ключом и значением как отдельные аргументы:
(assoc {:a :v} :f :r) ;;=> {:f :r, :a :v}
Или вы можете использовать merge
с двумя (или больше) карты в качестве аргументов:
(merge {:a :v} {:f :r}) ;;=> {:f :r, :a :v}
Специальная структура, о которой вы думаете, может быть MapEntry
. Вот что представляют собой элементы в последовательности, созданной вызовом seq
на карте.
Например:
(seq a-map) ;;=> ([:a :v] [:f :r])
(first (seq a-map)) ;;=> [:a :v]
(-> a-map seq first class) ;;=> clojure.lang.MapEntry
Записи карты выглядят и ведут себя так же, как векторы, с одним дополнением. Вы можете использовать функции key
и val
для доступа к ключу и значению соответственно (фактически эквивалентны (get map-entry 0)
и (get map-entry 1)
).
(key map-entry) ;;=> :a
(val map-entry) ;;=> :v
Вы можете conj
ввести запись карты на карту точно так же, как и вектор.
19.02.2014