view 6-Clojure/collection-type.clj @ 84:920b50be0fe5

Add notes (and failed code) for blocking queue
author IBBoard <dev@ibboard.co.uk>
date Sun, 09 Jun 2019 12:07:10 +0100
parents 29025305bbb7
children
line wrap: on
line source

(def classmap {
        "class clojure.lang.PersistentArrayMap" :map,
        "class clojure.lang.PersistentTreeMap" :map,
        "class clojure.lang.PersistentList$EmptyList" :list,
        "class clojure.lang.PersistentList" :list,
        "class clojure.lang.PersistentVector" :vector,
        "class clojure.lang.PersistentTreeSet" :set,
        "class clojure.lang.PersistentHashSet" :set
    })
(defn collection-type [col]
    "Writes :list, :map, set or :vector based on the collection's type"
    ; There's probably a better way that accounts for inheritance,
    ; but this works and uses the "map is a function with a lookup" approach!!
    ;
    ; We can't do this with classes directly, because of "java.lang.IllegalArgumentException: Duplicate key: (class ())"
    ; because of a clash with (class []), even though they're different and (hash …) gives different answers!
    (classmap (str (class col))))

(println (collection-type ()))
(println (collection-type (list 1 2 3)))
(println (collection-type []))
(println (collection-type [1 2 3]))
(println (collection-type #{}))
(println (collection-type (sorted-set)))
(println (collection-type (sorted-map)))
(println (collection-type {}))
(println (collection-type "not a collection"))
(println)


(def classmap2 {
        (class {}) :map,
        (class (sorted-map)) :map,
        (class ()) :list,
        (class (list 1)) :list,
        (class #{}) :set,
        (class (sorted-set)) :set
    })
(defn collection-type2 [col]
    "Writes :list, :map, set or :vector based on the collection's type"
    ; There's probably a better way that accounts for inheritance,
    ; but this works and uses the "map is a function with a lookup" approach!!
    ;
    ; The first IF works around the duplicate key issue (at least with this implementation of maps)
    (if (= (class []) (class col)) :vector (classmap2 (class col))))

(println (collection-type2 ()))
(println (collection-type2 (list 1 2 3)))
(println (collection-type2 []))
(println (collection-type2 [1 2 3]))
(println (collection-type2 #{}))
(println (collection-type2 (sorted-set)))
(println (collection-type2 (sorted-map)))
(println (collection-type2 {}))
(println (collection-type2 "not a collection"))
(println)

; Use (bases <class>) to find the parent classes
(defn collection-type3 [col]
    "Writes :list, :map, set or :vector based on the collection's type"
    (let [col_class (class col)] 
        (if (isa? col_class clojure.lang.IPersistentList) :list
            (if (isa? col_class clojure.lang.APersistentVector) :vector
                (if (isa? col_class clojure.lang.APersistentMap) :map
                    (if (isa? col_class clojure.lang.APersistentSet) :set)
                )
            )
        )
    )
)

(println (collection-type3 ()))
(println (collection-type3 (list 1 2 3)))
(println (collection-type3 []))
(println (collection-type3 [1 2 3]))
(println (collection-type3 #{}))
(println (collection-type3 (sorted-set)))
(println (collection-type3 (sorted-map)))
(println (collection-type3 {}))
(println (collection-type3 "not a collection"))