提问者:小点点

Clojure:(七周七种语言)获取收集和打印类型-对我的解决方案的反馈?


我正在使用《七周七种语言》一书来学习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)))

它工作得很好,但我觉得我没有抓住重点,这里有人有什么见解/建议/指导吗?它看起来如此丑陋和优雅。


共2个答案

匿名用户

其他答案取决于测试充满危险的集合的具体类型。

例如,作为性能优化,地图对不同大小有不同的具体实现。

考虑:

(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