2012-01-25 45 views
7

Clojure中,我可以解構的地圖是這樣的:地圖重組

(let [{:keys [key1 key2]} {:key1 1 :key2 2}] 
    ...) 

這是類似的CoffeeScript的方法:

{key1, key2} = {key1: 1, key2: 2} 

CoffeeScript中也可以做到這一點:

a = 1 
b = 2 
obj = {a, b} // just like writing {a: a, b: b} 

在Clojure中有這樣的捷徑嗎?

回答

10

它沒有提供,但可以用一個相當簡單的宏來實現:

 
(defmacro rmap [& ks]    
`(let [keys# (quote ~ks) 
     keys# (map keyword keys#) 
     vals# (list [email protected])] 
    (zipmap keys# vals#))) 
 
user=> (def x 1) 
#'user/x 
user=> (def y 2) 
#'user/y 
user=> (def z 3) 
#'user/z 
user=> (rmap x y z) 
{:z 3, :y 2, :x 1} 
1

簡短的回答是:不。

主要原因是在Clojure中,不僅關鍵字而且任何值都可以用作地圖中的關鍵字。而且,逗號是Clojure中的空格。所以{a, b}相同{a b},並會導致一個鍵值對,其中關鍵是什麼a計算爲一個地圖。

然而,您可以編寫一個宏,該宏使用符號列表並使用符號的名稱(轉換爲關鍵字)作爲關鍵字並將符號評估爲值來構建映射。

2

我在useful中爲此寫了一個簡單的宏,它可以讓你編寫爲(keyed [a b])。或者,您可以將地圖解構的:strs和:syms行爲與(keyed :strs [a b])並行,後者擴展爲{"a" a, "b" b}

+0

有用確實看起來很有用!有沒有文件的地方? – benekastah

+0

@benekastah不是。您可以閱讀源代碼,並查看測試 - 大多數功能都以一種明確的方式進行測試,從而明確了它們應該如何使用。 – amalloy

0

我不認爲這提供了用Clojure箱..但嘿,這是Lisp和我們可以使用宏來有這樣的事情:

(defmacro my-map [& s] 
    (let [e (flatten (map (fn [i] [(keyword (str i)) i]) s))] 
    `(apply hash-map [[email protected]])) 
) 

用法:

(def a 10) 
(def b 11) 

(def result (my-map a b)) 

結果將會是你的地圖