2016-05-27 19 views
0

我有一個關於兩個功能,一個走一個完整的地圖和其他特定的關鍵字,像這樣一個問題:Clojure的自毀圖來分析關鍵參數

(def mapVal 
{:test "n" 
    :anotherKey "n"}) 

(defn functionTest 
[& {:keys [test anotherKey] :or {:test "d" :anotherKey "d"}}] 
(println :test :anotherKey)) 

(defn mapFunc 
[map] 
(functionTest (get-in map [:test :anotherKey]))) 

的目標將是在參數所有的鍵map將被正確地傳遞給functionTest。無論如何,這可以工作?我嘗試了一些東西,但我不能獲得傳遞給functionTest的所有關鍵字和值。我不想要的只是地圖的值,它應該通過關鍵字和值傳遞給其他函數。

回答

1

你很近。一些事情應該清除它。

首先,當您使用[& varname]聲明參數時,意味着varname將成爲包含所有額外參數的列表。所以你不需要在這裏使用'&'來解構輸入。相反,你只需要命名你想成爲變量的鍵。

試試這個:

(defn functionTest 
[{:keys [test anotherKey]}] 
(println test anotherKey)) 

而另一個問題是使用get-in。與get-in你正在通過嵌套數據結構定義一個「路徑」與該向量。例如,給定:

{:first {:a 1 :b 2} :second {:c 3 :d 4}} 

你可以在:second:c使用get-in來獲取值與此:

(get-in {:first {:a 1 :b 2} :second {:c 3 :d 4}} [:second :c]) 

在你的情況,你不需要使用get-in在所有。你只需要傳遞整個地圖。您在functionTest中定義的解構將處理其餘部分。下面是我做了工作:

(defn mapFunc 
[map] 
(functionTest map)) 

我也建議你不要,因爲它與map功能衝突命名變量「map」。

0

get-in用於訪問嵌套關聯數據結構。

(def m {:a {:x 1}}) 
(get-in m [:a :x]) ;;=> 1 

解構映射後,這些值在範圍內,並通過符號訪問。你的榜樣應該是這樣的:

(def mapVal 
    {:test "n" 
    :anotherKey "n"}) 

(defn functionTest 
    [& {:keys [test anotherKey] 
     :or {:test "d" :anotherKey "d"}}] 
    (println test anotherKey)) 

(defn mapFunc 
    [m] 
    (apply functionTest (apply concat (select-keys m [:test :anotherKey])))) 


(mapFunc mapVal) ;;=> prints: n n 

你必須去通過這個,因爲functionTest在接受裸鍵值對作爲可選參數(那些到&的右側),如:

(functionTest :test "n" 
       :anotherKey "n") 
;;=> Also prints: n n 

select-keys返回的地圖與僅在指定的鍵:

(select-keys mapVal [:test]) 
;; => {:test "n"} 

施加concat到毫安p返回鍵和值的平坦SEQ:用Clojure代碼

(+ [1 2 3]) ;;=> Error. 
(apply + [1 2 3]) ;; => 6 

作爲附帶說明,以往:

(apply concat (select-keys mapVal [:test :anotherKey])) 
;; => (:test "n" :anotherKey "n") 

apply應用一個函數的SEQ,彷彿SEQ是它的參數列表,對於大多數人來說,蛇的情況比駱駝更受歡迎。