地图重组

时间:2012-01-25 08:39:59

标签: clojure coffeescript destructuring

在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中有这样的快捷方式吗?

4 个答案:

答案 0 :(得分:10)

它未提供,但可以使用相当简单的宏实现:

(defmacro rmap [& ks]            
 `(let [keys# (quote ~ks)
        keys# (map keyword keys#)
        vals# (list ~@ks)]
    (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 :(得分:2)

我在useful中为此编写了一个简单的宏,可以将其写为(keyed [a b])。或者,您可以使用(keyed :strs [a b])将地图解构的:strs和:syms行为与{"a" a, "b" b}相对应。

答案 2 :(得分:1)

简短的回答是:不。

主要原因是在Clojure中,不仅关键字而且任何值都可以用作地图中的关键字。此外,逗号是Clojure中的空白。因此{a, b}{a b}相同,并且会生成一个包含一个键值对的地图,其中键是a评估的内容。

然而,您可以编写一个宏来获取符号列表,并使用符号名称(转换为关键字)作为关键字并将符号评估为值来构建地图。

答案 3 :(得分:0)

我认为这不是开箱即用的。但是,这是lisp,我们可以使用宏来做这样的事情:

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

用法:

(def a 10)
(def b 11)

(def result (my-map a b))

结果将是您的地图