Reputation: 143
I have a vector of maps which represents a DataFrame. I want to compute a new column (key/val pairs for all maps in the vector). Need some help to do this in the most efficient and idiomatic way.
(def dt [{:foo 10 :bar 20 :cat "A"}
{:foo 15 :bar 10 :cat "B"}
{:foo 12 :bar 15 :cat "C"}
{:foo 16 :bar 22 :cat "A"}
{:foo 13 :bar 11 :cat "B"}
{:foo 10 :bar 19 :cat "C"}])
What I want to do is define :baz = :foo + :bar. I can get the computation done with a map operation as follows.
(map #(+ (:foo %) (:bar %)) dt)
I would prefer to write a function where the vector is maps is the last argument, so that I can chain operations with the thread-last macro
Something like this:
(->> dt
(filter #(= (:foo %) 10))
(compute-new-column #(...)))
I am beginner in both Clojure and FP, so any additional insights would be appreciated as well.
Upvotes: 2
Views: 241
Reputation: 76
If I understand your question correctly you want to add a new key value pair to each map in your collection based on :foo
and :bar
.
(defn compute-new-column [row]
(assoc row :baz (+ (:foo row) (:bar row))))
Then you can map this function in your thread macro. This is easily done with an anonymous function too as you are doing in your filter.
(->> dt
(filter #(= (:foo %) 10))
(map compute-new-column))
({:foo 10, :bar 20, :cat "A", :baz 30} {:foo 10, :bar 19, :cat "C", :baz 29})
Upvotes: 2