Как преобразовать вектор в карту по этому правилу?

РЕШЕНО САМОСТОЯТЕЛЬНО

(defn parse-args
  ([args]
   (parse-args args {}))
  ([[fst sec & more] rst]
   (let [value? (fn [x] (and (not (keyword? x))
                             (not (map? x))))]
     (cond
       (and (keyword? fst)
            (keyword? sec)) (parse-args (cons sec more) (merge rst {fst true}))
       (and (keyword? fst)
            (value? sec)) (parse-args more (merge rst {fst sec}))
       :else rst
       ))))


*я новичок в clojure

например, есть vec, как показано ниже:

[:enchant :type "Fire Aspect" :level 123]

попробуйте преобразовать его в:

{:enchant true :type "Fire Aspect" :level 123}

обратите внимание, что исходный vec был каким-то образом «перемежается»
но не каждый ключ имеет свое «значение» (например, :enchant)
и я просто хочу узнать их и рассматривать как логическое значение
с true в качестве значения по умолчанию


я пытался использовать:

(defn parse-arg [args toggle-coll]
  (let [is-value? #(not (and (keyword? %)
                             (map? %1)))]
    (reduce (fn [k1 k2]
              (merge
                (cond
                  (and (keyword? k1)
                       (keyword? k2)) ({} {k1 true})
                  (and (keyword? k1)
                       (is-value? k2)) ({} {}) ; and soon i found this method is difficult and clumsy
                  (and (map? k1)
                       (is-value? k2)) ({} {})
                  (and (map? k1)
                       (keyword? k2)) ({} {})
                  ;; omitted)
                )
              )
            args)))

@amalloy, это не дубликат преобразования seq -> hash-map, речь идет о выводе отсутствующих значений во входном векторе со значением по умолчанию true

leetwinski 02.04.2023 11:08
Введение в одну из самых важных концепций в React - функциональное программирование
Введение в одну из самых важных концепций в React - функциональное программирование
React разработан с использованием концепции функционального программирования, поэтому понимание функционального программирования важно для изучения...
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Фото ️🔁 Radek Jedynak 🔃 on ️🔁 Unsplash 🔃
Что такое Java 8 Streams API? Java 8 Stream API
1
1
86
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

clojure.spec можно использовать для выражения обычного языка для обработки пропущенных значений. Здесь мы определяем спецификацию ::input для мини-языка:

(require '[clojure.spec.alpha :as s])

(spec/def ::input (s/* (s/cat :k keyword? :v (s/? (complement keyword?)))))

Затем мы можем проанализировать входной вектор с помощью соответствия и поместить его в карту с помощью картыпреобразователь пинга:

(defn parse-args [args]
  (into {}
        (map (juxt :k #(:v % true)))
        (s/conform ::input args)))
Ответ принят как подходящий

мы также можем обработать входные данные по окнам из 2-х элементов и вставить true между двумя ключевыми словами:

(defn parse-args [data]
  (->> (concat data [::end])
       (partition 2 1)
       (mapcat (fn [[a :as pair]] 
                 (if (every? keyword? pair)
                   [a true]
                   [a])))
       (apply hash-map)))

::end kv добавляется для обработки оборванного ключевого слова в конце последовательности, если таковое имеется.

user> (parse-args [:a :b 1 :c 10 :d])
;;=> {:c 10, :b 1, :d true, :a true}

Хорошее решение! Я добавил что-то похожее, но решил снова удалить его, потому что забыл об обработке этого висящего ::end.

Rulle 02.04.2023 11:48

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