我将说明您可以使用的其他一些方法,这些方法可以与 leetwinski 说明的方法结合使用。像 leetwinski 一样,我建议使用哈希映射作为最终结构,而不是包含向量的三个符号。这取决于你。
如果你愿意,你可以使用 core.matrix 的 transpose 来做 leetwinski 对 (apply map vector ...) 所做的事情:
(require '[clojure.core.matrix :as mx])
(mx/transpose '(["atom" "neutron" "photon"] [10 22 3] [23 23 67]))
产生:
[["atom" 10 23] ["neutron" 22 23] ["photon" 3 67]]
transpose 旨在处理任何类型的实现 core.matrix 协议的矩阵,并且正常的 Clojure 序列序列被 core.matrix 视为矩阵。
要生成地图,这是一种方法:
(into {} (map #(vector (keyword (first %)) (rest %))
(mx/transpose '(["atom" "neutron" "photon"] [10 22 3] [23 23 67]))))
产生:
{:atom (10 23), :neutron (22 23), :photon (3 67)}
keyword 将字符串变成关键字。 #(vector ...) 生成一对,(into {} ...) 获取对的序列并从中生成哈希映射。
或者,如果您想要 vars 中的向量,正如您所指定的,那么您可以使用 leetwinski 的 let 方法的变体。我建议不要 defing 符号 atom,因为这是 Clojure 中标准函数的名称。
(let [[adam neutron proton] (mx/transpose
(rest '(["atom" "neutron" "photon"]
[10 22 3]
[23 23 67])))]
(def adam adam)
(def neutron neutron)
(def proton proton))
在let 中使用def 并不是一种很好的形式,但您可以这样做。另外,我不建议将let 定义的局部变量命名为与顶级变量相同的名称。如您所见,如果使defs 令人困惑。我在这里故意这样做只是为了展示范围规则的工作原理:在(def adam adam) 中,“adam”的第一个实例表示定义的顶级变量,而“adam”的第二个实例表示定义的本地变量通过let,包含[10 23]。结果是:
adam ;=> [10 23]
neutron ;=> [22 23]
proton ;=> [3 67]
(我认为可能有些微妙之处我表达不正确。如果是这样,毫无疑问会有人对此发表评论。)