如何根据这个规则将矢量图转换成地图?

问题描述 投票:0回答:2

自己解决

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

functional-programming clojure
2个回答
1
投票

我们也可以通过2个item的窗口处理输入数据,在两个关键字之间插入

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}

1
投票

clojure.spec 可用于表达处理缺失值的常规语言。在这里,我们为迷你语言定义了一个规范

::input

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

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

然后我们可以使用

conform
解析输入向量,并使用
into
ping 换能器将其放入
map
地图:

(defn parse-args [args]
  (into {}
        (map (juxt :k #(:v % true)))
        (s/conform ::input args)))
© www.soinside.com 2019 - 2024. All rights reserved.