如何有条件地连接到clojure向量
在clojure中有没有一种更干净的方法来执行以下操作如何有条件地连接到clojure向量,clojure,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
(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]
我所说的“清洁剂”是指与此更接近的东西:
(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]
请注意,我可能希望对thing
中的任何键调用任意函数(例如this
,that
,另一个
),并将结果放入返回的向量中。重要的是,如果键在映射中不存在,则不应在向量中放置nil
这与类似,但输出是矢量而不是贴图,因此我无法使用merge
;;; 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]
注意
keep
只抛出nil
false
将包含在输出中。难道你不想要(vec(vals thing))?@DiegoBasch:是的,这就是他想要的。不,对不起@DiegoBasch,我想要能够调用给定键上的任意函数。我对示例进行了编辑,以使其更加清晰。如果错误
也应被丢弃,请使用(筛选标识(映射(%thing))
代替保留
调用。请参阅我的编辑。可以使用keep
调用任意函数吗?我想我可以有一些伞形函数来分配密钥名,但这开始变得难看。正如答案中提到的,你可以在传递给keep
的sequalable中放入任意函数make vector
。特别是,您可以将[:a:b:c]
替换为[(comp this:a)(comp that:b)(comp the other:c)]
,以获得当前包含在问题文本中的非工作生成向量的版本,该版本实际上在输出中省略了任何nil
。(或者你可以把(comp this:a)
拼成#(this(:a%))
,当然。)另请参见(doc keep)
(基本上它的工作原理类似于map
,但从输出中丢弃nil
)。嗯,这并不是我想要的。我的例子不好。完全重新编辑问题或删除问题并重新提问更好吗?好的,如果我理解正确,您希望在对值调用函数之前进行过滤(以查看是否存在键)(因此您不希望调用此
,那个
或另一个
,从您的nil
示例中)。在这种情况下,mobyte的答案应该适合你。这可能就是stand所寻找的答案。作为一个小调整,在Clojure 1.4reduce kv
中,它更适合这项工作。
(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]