在Clojure中初始化地图的快捷方式

时间:2018-02-07 22:57:23

标签: clojure hashmap

所以在ES6中,我可以这样做:

let x=1 y=1 z=1
let o = {x, y,z}
console.log(o.x)  //prints 1

我没有看到任何内置方式在clojure中做这样的事情。可以做一个比这更好的方法来从一个带有许多参数的函数返回一个映射吗?

(defn foo
  [x y z]
  {:x x :y y :z z})

(pprint (get  ( foo 1 2 3) :x)) ;prints 1

2 个答案:

答案 0 :(得分:3)

为什么这样做不是一个好主意有十几个原因,但是关于lisp的一个很酷的事情是你可以做你想做的事情,如果语言不能做你想做的事,你可以扩展它。

这是一个简单的宏

(defmacro infer-map [& args]
  {:pre [(every? symbol? args)]}
  `(hash-map
     ~@(interleave
         (map (comp keyword name) args)
         args)))

用法:

(let [x 1 y 2 z 3]
  (infer-map x y z))
=> {:y 2, :z 3, :x 1}

答案 1 :(得分:1)

您可以使用vals->contextwith-context in the Tupelo Clojure library执行此操作。单元测试显示了此功能:

(dotest
  (let [ctx     (let [a 1
                      b 2
                      c 3
                      d 4
                      e 5]
                  (vals->context a b c d e)) ]
    (is= ctx {:a 1 :b 2 :c 3 :d 4 :e 5})

    (let [{:keys [a b c d e]} ctx]
      (is= [a b c d e] [1 2 3 4 5]))

    (with-context ctx [a b c d e]
      (is= [a b c d e] [1 2 3 4 5])
      (is= 15 (+ a b c d e)))
    (with-context ctx [b a d c e] ; order doesn't matter
      (is= [a b c d e] [1 2 3 4 5])
      (is= 15 (+ a b c d e)))

    (throws?
      (with-context ctx [x y z]
        (println "shouldn't ever get here")))))