Pregunta

In clojure, I can destructure a map like this:

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

which is similar to CoffeeScript's method:

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

CoffeeScript can also do this:

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

Is there a shortcut like this in Clojure?

¿Fue útil?

Solución

It's not provided, but can be implemented with a fairly simple macro:

(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}

Otros consejos

I wrote a simple macro for this in useful, which lets you write that as (keyed [a b]). Or you can parallel the :strs and :syms behavior of map destructuring with (keyed :strs [a b]), which expands to {"a" a, "b" b}.

The short answer is: no.

The main reason is that in Clojure, not only keywords but any value can be used as a key in a map. Also, commas are whitespace in Clojure. So {a, b} is the same as {a b} and will result in a map with one key-value pair, where the key is whatever a evaluates to.

You could however write a macro that takes a list of symbols and builds a map with the names of the symbols (converted to keywords) as keys and the evaluations of the symbols as values.

I don't think that is provided out of the box in clojure .. but hey this is lisp and we can use macros to have something like this:

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

Usage:

(def a 10)
(def b 11)

(def result (my-map a b))

result would be your map

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top