Search code examples
clojure

Idiomatic way to wrap object into collection (if it's not a collection already) in Clojure?


I have (for instance) a mix of data structures such as {:name "Peter" :children "Mark"} and {:name "Mark" :children ["Julia" "John"] i.e. :children value is either a single string or a collection of strings. Other functions in my code expect that the value of :children is always a collection of strings, so I need to adapt the data for them.
Of course I can use something like:

(defn data-adapter [m]
  (let [children (:children m)]
    (assoc m :children 
             (if (coll? children) 
               children
               [children]))))

But is there a more idiomatic/laconic way?


Solution

  • I think you will have to take no for an answer.

    (if (coll? x) x [x]) is about as terse and expressive as it gets. It’s what people usually use for this problem (sometimes with sequential? instead of coll?).

    cond-> enthusiasts like me sometimes try to use it in place of a simple conditional, but here it is no improvement:

    (cond-> x (not (coll? x)) vector)
    

    In the context of your code, however, you can do a little better. A lookup and association is best expressed with update:

    (defn data-adapter [m]
      (update m :children #(if (coll? %) % [%])))