我正在使用《七周七种语言》一书来学习Clojure,我觉得我错过了重点和/或没有得到它。
问题:
编写一个名为(Collection ty-type coll)的函数,根据集合coll的类型返回: list、:map或:向量。
我的解决方案:
(defn collection-type
"returns collection type for list map or vector"
[col]
(def look-up {:list "class clojure.lang.PersistentList", :map "class clojure.lang.PersistentArrayMap", :vector "class clojure.lang.PersistentVector"})
(if (= (look-up :list) (str (type col))) (println :list))
(if (= (look-up :map) (str (type col))) (println :map))
(if (= (look-up :vector) (str (type col))) (println :vector)))
它工作得很好,但我觉得我没有抓住重点,这里有人有什么见解/建议/指导吗?它看起来如此丑陋和优雅。
其他答案取决于测试充满危险的集合的具体类型。
例如,作为性能优化,地图对不同大小有不同的具体实现。
考虑:
(type {})
;=> clojure.lang.PersistentArrayMap
(type (zipmap (range 100) (range 100)))
;=> clojure.lang.PersistentHashMap
既然Clojure已经有谓词来测试必要的集合,为什么不使用它们并使解决方案更加健壮
(defn collection-type [coll] (condp #(%1 %2) coll
map? :map
vector? :vector
list? :list))
编辑
尽管下面回答了这个问题,但它并没有修复@sw1nn指出的提供代码中的错误。
我们如何简化这一点?
查找
映射以给出给定类型的关键字标签。使用查找
映射作为函数(正如您已经做的那样),我们得到
(defn collection-type
"returns collection type for list map or vector"
[coll]
(let [look-up {clojure.lang.PersistentList :list
clojure.lang.PersistentArrayMap :map
clojure.lang.PersistentVector :vector}]
(look-up (type coll))))
然后呢
(collection-type [])
;:vector
(collection-type (list 1))
;:list
但是
(collection-type ())
;nil
自
(type ())
;clojure.lang.PersistentList$EmptyList