Return plain map from a Clojure record

后端 未结 3 1496
渐次进展
渐次进展 2021-01-19 21:54

I have a record:

(defrecord Point [x y])
(def p (Point. 1 2))

Now I want to extract just the map from the record. These ways get the job do

相关标签:
3条回答
  • 2021-01-19 22:02

    A. Webb suggested the much-simpler (into {} p) in the comments. Thanks!

    Here is a code snippet that is more general; it works for recursive records:

    (defrecord Thing [a b])
    (def t1 (Thing. 1 2))
    (def t2 (Thing. 3 4))
    (def t3 (Thing. t1 t2))
    
    (defn record->map
      [record]
      (let [f #(if (record? %) (record->map %) %)
            ks (keys record)
            vs (map f (vals record))]
        (zipmap ks vs)))
    
    (record->map t3)
    ; {:b {:b 4, :a 3}, :a {:b 2, :a 1}}
    
    0 讨论(0)
  • 2021-01-19 22:03

    Records are maps

    (defrecord Thing [a b])
    
    (def t1 (Thing. 1 2))
    (instance? clojure.lang.IPersistentMap t1) ;=> true
    

    So, in general there is no need to coerce them into a APersistentMap type. But, if desired you do so with into:

    (into {} t1) ;=> {:a 1, :b 2}
    

    If you want to traverse an arbitrary data structure, including nested records, making this transformation, then use walk

    (def t2 (Thing. 3 4))
    (def t3 (Thing. t1 t2))
    (def coll (list t1 [t2 {:foo t3}]))
    
    (clojure.walk/postwalk #(if (record? %) (into {} %) %) coll)
    ;=> ({:a 1, :b 2} [{:a 3, :b 4} {:foo {:a {:a 1, :b 2}, :b {:a 3, :b 4}}}])
    
    0 讨论(0)
  • 2021-01-19 22:15

    I also wrote a general function that converts records to maps for (most) arbitrary Clojure data structures:

    (defn derecordize
      "Returns a data structure equal (using clojure.core/=) to the
      original value with all records converted to plain maps."
      [v]
      (cond
        (record? v) (derecordize (into {} v))
        (list? v) (map derecordize v)
        (vector? v) (mapv derecordize v)
        (set? v) (set (map derecordize v))
        (map? v) (zipmap (map derecordize (keys v)) (map derecordize (vals v)))
        :else v))
    

    I know this is unusual. This is useful when you need to export a data structure without records.

    0 讨论(0)
提交回复
热议问题