我正在使用 Seven Weeks Seven Languages 这本书学习Clojure,我觉得我错过了这个观点和/或没有得到它。
问题:
编写一个名为(collection-type col)的函数,它返回:list,:map, 或:基于集合col的类型的向量。
我的解决方案:
(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)))
它工作正常,但我觉得我错过了重点,有没有人在这里有任何见解/建议/指导?它看起来很丑陋而且优雅。
答案 0 :(得分:3)
修改的
虽然以下内容回答了问题,但它并未修复@sw1nn所提供的提供代码中的错误。
我们如何简化这个?
look-up
地图以提供给定类型的关键字标记。使用look-up
地图作为一种功能(就像你已经做的那样),我们得到了
(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
答案 1 :(得分:3)
其他答案取决于测试充满危险的集合的具体类型。
例如,Maps作为性能优化,针对不同的大小具有不同的具体实现。
考虑:
(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))