user=> (into {} '((:a :b) (:c :d)))
投掷:ClassCastException clojure.lang.Keyword cannot be cast to java.util.Map$Entry clojure.lang.ATransientMap.conj (ATransientMap.java:44)
.
而:
user=> (into {} (list [:a :b] [:c :d]))
很好。这是一个奇怪的区别,因为很多时候其他函数返回列表时,它们必须从向量开始:
user=> (into {} (partition 2 (interleave [:a :b] [:c :d])))
会扔,因为它partition 2 ...)
导致((:a :c) (:b :d))
.所以这很烦人。你基本上必须记住方法的返回类型和函数(如into
)的特定行为,或者你必须让东西爆炸并在你发现它时修复它 (into {} (map vec (partition 2 (interleave [:a :b] [:c :d]))))
.
into
不喜欢这些对作为列表有什么具体原因吗?
原因是正如您所说,只有向量对可用于构建地图。我不知道存在此限制的实际原因。但是还有其他几种构建哈希映射的方法。如果您发现自己使用分区,也许答案是使用替代构造方法。
如果您有键和值的并行序列:
(zipmap [:a :c] [:b :d])
如果所有项目都按平面顺序排列:
(apply hash-map [:a :b :c :d])
从序列构建映射:
(into {} (for [[k v] xs]
[k (transform v)]))
我从来没有意识到这行不通! 别忘了:
(apply hash-map (interleave [:a :b] [:c :d]))
;=> {:b :d, :a :c}
由于hash-map
从标量参数隐式创建对:
(hash-map :a :c :b :d)
;=> {:b :d, :a :c}
你真的不需要(partition 2...)
这是问题的根源。