RatavaWen
RatavaWen

Reputation: 147

How to get the sequence of keys for each map in a list of maps in Clojure?

So I've got the following attempt to map over a list of maps and I'm trying to get the sequence of keys that the 'keys' function returns just fine whenever I pass it a single map.

(map #(keys %) ({:a-id 1 :b 3 :c 2} {:d-id 3 :e 9 :c 1} {:a-id 3 :d-id 5 :c 2}))

which returns me a

java.lang.ClassCastException: null

I'm supposing this has something to do with the return type on keys being a sequence and by mapping over I'm guessing it's expecting a map return value??? I'm really not sure exactly why it's doing this, all I know is that it'd be dern convenient if I could get it to do in mapping what it's doing for me when I do a single application of

(keys {:a-id 1 :b 3 :c 2})

which is -- (:a-id :b :c)

Upvotes: 0

Views: 212

Answers (3)

Alan Thompson
Alan Thompson

Reputation: 29984

Even better is to just not use lists unless you really want to create a function call. Your original code, converted to a vector of 3 maps, works great:

user=> (map #(keys %) [{:a-id 1 :b 3 :c 2} {:d-id 3 :e 9 :c 1} {:a-id 3 :d-id 5 :c 2}] )
((:a-id :c :b) (:e :c :d-id) (:a-id :c :d-id))

We leave the outer parentheses in place since (map ...) is intended to be a function call. We change the inner list to a vector, since this emphasizes that it is data (as opposed to a function call). Quoting the list also works, but is unnecessarily complex. It like saying "I am making a function call, but don't evaluate it as a function call."

Upvotes: 0

Alex Miller
Alex Miller

Reputation: 70239

(map keys '({:a-id 1 :b 3 :c 2} {:d-id 3 :e 9 :c 1} {:a-id 3 :d-id 5 :c 2}))

Upvotes: 5

Joost Diepenmaat
Joost Diepenmaat

Reputation: 17761

({:a-id 1 :b 3 :c 2} {:d-id 3 :e 9 :c 1} {:a-id 3 :d-id 5 :c 2})

Is a function call not a list. You should use list or a vector or quote the expression:

(list{:a-id 1 :b 3 :c 2} {:d-id 3 :e 9 :c 1} {:a-id 3 :d-id 5 :c 2})

Upvotes: 2

Related Questions