[英]How do I conj to a clojure vector conditionally
Is there a cleaner way to do something like the following in clojure? 在clojure中有更清洁的方法来执行以下操作吗?
(defn this [x] (* 2 x))
(defn that [x] (inc x))
(defn the-other [x] (-> x this that))
(defn make-vector [thing]
(let [base (vector (this (:a thing))
(that (:b thing)))]
(if-let [optional (:c thing)]
(conj base (the-other optional))
base)))
(make-vector {:a 1, :b 2}) ;=> [2 3]
(make-vector {:a 1, :b 2, :c 3}) ;=> [2 3 7]
By "cleaner" I mean something closer to this: 通过“清洁”,我的意思是更接近这个:
(defn non-working-make-vector [thing]
(vector (this (:a thing))
(that (:b thing))
(if (:c thing) (the-other (:c thing)))))
(non-working-make-vector {:a 1, :b 2} ;=> [2 3 nil] no nil, please!
(non-working-make-vector {:a 1, :b 2, :c 3} ;=> [2 3 7]
Note that I might want to call some arbitrary function (eg this
, that
, the-other
) on any of the keys in thing
and place the result in the returned vector. 请注意,我可能想要在thing
任何键上调用一些任意函数(例如this
, that
, the-other
),并将结果放在返回的向量中。 The important thing is that if the key doesn't exist in the map it should not put a nil
in the vector. 重要的是,如果地图中不存在密钥,则不应在向量中添加nil
。
This is similar to this question but the output is a vector rather than a map so I can't use merge
. 这类似于这个问题,但输出是矢量而不是地图,所以我不能使用merge
。
(defn this [x] (* 2 x))
(defn that [x] (inc x))
(defn the-other [x] (-> x this that))
(def k-f-map {:a this
:b that
:c the-other})
(def m1 {:a 1 :b 2})
(def m2 {:a 1 :b 2 :c 3})
(defn make-vector [k-f-map m]
(reduce (fn [res [fk fv]]
(if (fk m)
(conj res (fv (fk m)))
res))
[] k-f-map))
(make-vector k-f-map m1)
-> [2 3]
(make-vector k-f-map m2)
-> [2 3 7]
;;; replace [:a :b :c] with a vector of arbitrary functions
;;; of your choice, or perhaps accept a seqable of functions
;;; as an extra argument
(defn make-vector [thing]
(into [] (keep #(% thing) [:a :b :c])))
;;; from the REPL:
(make-vector {:a 1 :b 2})
; => [1 2]
(make-vector {:a 1 :b 2 :c 3})
; => [1 2 3]
Note that keep
only throws out nil
; 请注意, keep
只抛出nil
; false
will be included in the output. false
将包含在输出中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.