我想将两个(或更多)谓词应用于单个值.例如,假设我想测试一个值是否为正整数:
(defn posint? [n]
(and (integer? n) (pos? n)))
Run Code Online (Sandbox Code Playgroud)
这样做,但如果我想组成应用的谓词怎么办?我不想为每个可能的谓词组合编写函数.
说我有一个Java枚举.例如:
public enum Suits {CLUBS, DIAMONDS, HEARTS, SPADES};
Run Code Online (Sandbox Code Playgroud)
通常情况下,我可以用这样的枚举做一些clojure:
(defn do-something []
(let [s Suits/DIAMONDS] (...)))
Run Code Online (Sandbox Code Playgroud)
但是,我想编写一个clojure函数,允许调用者指定要使用的枚举实例:
(defn do-something-parameterized [suit]
(let [s Suits/suit] (...)))
Run Code Online (Sandbox Code Playgroud)
我们的想法是让呼叫者传递"DIAMONDS",并有DIAMONDS枚举实例获取绑定到s的let.
我可以cond匹配参数,但这似乎比必要的笨拙.我想我也可以使用宏来构造Suits/添加到suit.这是做到这一点的方式还是有一种我失踪的非宏观方式?
我有一个返回地图的函数.键是静态的,但值是有条件的.像这样:
(defn map-returning-function [x y]
{:a (if (some-test-fn x) "one value" "other value"
:b (if (some-test-fn x) 15 25
:c (if (different-test y) :one :two})
Run Code Online (Sandbox Code Playgroud)
是否有一些更优雅的方法来实现这一点,而无需if为每个值编写测试?我能想到的另一种方式是
(defn another-map-returning-function [x y]
(if (some-test-fn x)
{:a "one value", :b 15, :c (if (different-test y) :one :two)}
{:a "other value" :b 25, :c (if (different-test y) :one :two)}))
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎并不好,因为它重复了条件的每个分支的键名,并重复了函数调用different-test.天堂禁止我需要一个cond而不是一个if.
我今天发现了这个clojure问题:
(condp contains? some-set
"foo" "foo's in thar"
"bar" "bar's in thar"
"t'aint thar")
Run Code Online (Sandbox Code Playgroud)
我们的想法是在some-set包含值的第一个匹配项下返回字符串.如果集合中没有值,则返回最后一个值.问题是,contains?函数首先采集集合然后是密钥并condp首先需要密钥.
我通过写一个函数"修复"它:
(defn reverse-params [f] (fn [a b] (f b a))
Run Code Online (Sandbox Code Playgroud)
并用一个电话代替它:
(condp (reverse-params contains?) some-set
"foo" "foo's in thar"
"bar" "bar's in thar"
"t'aint thar")
Run Code Online (Sandbox Code Playgroud)
哪个有效,但我的问题是我错过了一些更好的方法(也许通过使用some)?我可以使用,cond但我想这样可以节省一些打字.
是否有更干净的方法在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]
Run Code Online (Sandbox Code Playgroud)
我所说的“更清洁”更接近于此:
(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 …Run Code Online (Sandbox Code Playgroud) 我需要运行两个命令.第一个创建一个文件,用作第二个的输入参数.我可以这样跑:
$ cmd1 p1 p2 > tmp.txt
$ cmd2 -i tmp.txt p3
Run Code Online (Sandbox Code Playgroud)
在-i对参数cmd2需要一个文件名.有没有办法在不创建tmp.txt文件的情况下在一行中执行此操作?
我试图想出一种通过将另一个映射中的函数应用于每个值来转换 clojure 哈希映射的方法。这是我到目前为止所拥有的:
(defn transform-map [m fm]
(into {} (for [[k v] m]
(let [mfn (get fm k identity)] [k (mfn v)])))
(def m {:a 0 :b 0 :c 0 :d 0})
(def fm {:a inc :b dec :c identity})
(transform-map m fm) ;=> {:a 1, :b -1, :c 0, :d 0}
Run Code Online (Sandbox Code Playgroud)
这很好用,但前提是每个函数都采用一个参数,即键的当前值。如果我想在函数映射中放置一个使用除同一键中的值以外的值的函数该怎么办?:a例如,假设我想将键和的总和放入:bkey 中:d?
我可以尝试这样的事情:
(assoc fm :d (fn[a b] (+ a b)))
Run Code Online (Sandbox Code Playgroud)
但是有没有办法可以改变我的transform-map函数,以便它在该函数调用中使用适当的参数?