Reputation: 541
I run into this problem a lot (more often in clojurescript) but haven't noticed how others deal with it. This is what I want:
[:div.container [:div.first "first"] [:div.second "second"] [:div.third "third"]]
And let's say I'm building it from a collection like: ["first" "second" "third"]
I'll pass the collection through a mapv
and wind up with (this code is a sketch, I'm not using it):
(mapv
#([(keyword (str "div." %)) %])
["first" "second" "third"])
=> [[:div.first "first"] [:div.second "second"] [:div.third "third"]]
And if I were to use it inside the container div, I'd get:
[:div.container [[:div.first "first"] [:div.second "second"] [:div.third "third"]]]
I've been using things like cons
to put the :div.container
at the front of the result of mapv
. But in my mind there should be a better way--like an opposite of reduce
. Is there such a thing?
Edit: I did find concat
and it looks like I've tried it before, but I get a sequence back. I want a vector. (vec (concat ... ))
is not ideal.
Upvotes: 0
Views: 442
Reputation: 41
Are you aware that [:ul ([:li "one"] [:li "two"])] will work as expected?
I think if you change (mapv f coll) to
(map f coll)
or
(doall (map f coll))
You'll get the result you're looking for.
Upvotes: 0
Reputation: 20194
The "opposite of reduce" is reduce.
(reduce (fn [v s]
(conj v [(keyword (str "div." s)) s]))
[:div.container]
["first" "second" "third"])
Upvotes: 1
Reputation: 1107
cons
is fine here -- it's been around since the dawn of Lisp and it's useful for exactly what you want to do here.
Here's how I'd approach this:
(defn containerize
[tag v]
(let [kw #(keyword (str tag "." %))]
(into []
(cons (kw "container")
(map (fn [x] [(kw x) x]) v)))))
Upvotes: 1
Reputation: 27756
How about:
(apply vector :div.container
(mapv #(vector (keyword (str "div." %)) %)
["first", "second", "third"]))
The idea is to use apply
to pass each element of the result of mapv
as an individual argument to vector
.
As a bonus, apply
admits other arguments before the collection argument, so we can stow the :div.container
there.
(Here using mapv
vs. map
would be indifferent.)
(Also, the "opposite" of reduce
is usually called unfold
in other languages, but I havent found the analogous function in the core Clojure libraries.)
Upvotes: 4