Карта реструктуризации - PullRequest
7 голосов
/ 25 января 2012

В ближайшем будущем я могу деструктурировать карту следующим образом:

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

10 голосов
/ 25 января 2012

Это не предусмотрено, но может быть реализовано с помощью довольно простого макроса:

(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}
2 голосов
/ 25 января 2012

Я написал для этого простой макрос в полезном , который позволяет записать это как (keyed [a b]).Или вы можете сравнить поведение stst и: syms при деструктуризации карты с (keyed :strs [a b]), которое расширяется до {"a" a, "b" b}.

1 голос
/ 25 января 2012

Краткий ответ: нет.

Основная причина в том, что в Clojure в качестве ключа на карте могут использоваться не только ключевые слова, но и любое значение.Кроме того, запятые являются пробелом в Clojure.Таким образом, {a, b} совпадает с {a b} и приведет к карте с одной парой ключ-значение, где ключ равен тому, что a оценивает до.

Однако вы можете написать макрос, который принимаетсписок символов и строит карту с именами символов (преобразованы в ключевые слова) в качестве ключей и оценки символов в качестве значений.

0 голосов
/ 25 января 2012

Я не думаю, что это предоставляется из коробки в clojure ... но эй, это шутка, и мы можем использовать макросы, чтобы иметь что-то вроде этого:

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

результатом будет ваша карта

...