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

时间:2014-09-11 07:10:34

标签: clojure

我正在使用 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)))

它工作正常,但我觉得我错过了重点,有没有人在这里有任何见解/建议/指导?它看起来很丑陋而且优雅。

2 个答案:

答案 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))