2012-02-03 127 views
4

我有一個clojure函數,如果特定條件爲真,需要將信息推入地圖,將該地圖用作另一個函數的參數。有條件調用函數有條件地調用函數

我有以下幾點,但是對重複調用bar函數感覺很笨拙。因此,如果(某事)是真的,我們會在調用bar函數之前將其他選項添加到opts參數中,否則我們只是傳遞它。

回答

7

第一件事是(= true (something))可以簡單地通過(something)沒有問題更換(除非你實際上是嘗試的true一個返回值,比如說,1返回值來區分)。如果返回值的選項是truefalse,則(something)本身可以正常工作。你也可以使用merge來代替into,這可能會稍微清晰些。

你可以嘗試

(bar (if (something) 
     (merge opts {:a b}) 
     opts)) 

這會工作爲好,儘管它需要調用merge不必要時(something)是假的,雖然與nil的第二個參數,merge應該很快返回。

(bar (merge opts 
      (when (something) 
       {:a b}))) 
+2

由於'(進入{}無)=> {}',你可以做'(巴(進入OPTS(時(東西){:AB })))'。也可以使用'merge'而不是'into'。 – Jonas 2012-02-04 05:39:31

+0

@Jonas謝謝 - 更新 – Retief 2012-02-04 05:44:27

0

將條件代碼重構爲函數。喜歡的東西:

(defn addAIfSomethig [opt] (if (something) (into opts {:a "A"}) opt)) 
(defn addBIfSomethig [opt] (if (something) (into opts {:b "B"}) opt)) 

然後在你的功能,你需要調用欄使用功能組成之前修改選擇。

(defn foo [opt] 
    (let [modifiers (comp addAIfSomethig addBIfSomethig)] 
     (bar (modifiers opt)) 
    )) 
+0

我真的很感謝倒票,但增加原因作爲評論會讓它變得難以捉摸 – Ankur 2012-02-05 11:55:27

+0

在Clojure中使用'camelCase'函數名是不慣用的。你可以編寫'(defn <* _-!magicalFruit!-_ *> [](+ 1 1))'',但是如果你不想讓你的代碼像「foo-bar」 ,'foo-bar?','foo-bar!'和(可能)'foo-> bar',除非有其他的理由。 – 2012-02-20 03:25:21

+0

感謝有關clojure(和一般lisp)風格的信息 – Ankur 2012-02-20 04:08:31

2

retief的答案沒錯。應該注意的是,if是Clojure中的一個表達式,而不僅僅是一個條件構造。因此,它有一個返回值,你可以使用返回值作爲參數傳遞給函數:

(bar (if (something)  
     (into opts {:a b}) 
     opts)) 

你可以把它作爲在Java中三元運算符。

0

注意,由於Clojure的1.5這個可以寫

(cond-> opts (something) (merge {:a b}))