Rob Buhler
Rob Buhler

Reputation: 2511

return sequence of clojure map values in a specific order

If I have a map, for example,

(def mymap { :b 1 :a 2 :d 3 :e 4 :f 5})

I can use vals to get a sequence of all of the values

(vals mymap)
;=> (1 2 3 4 5)

how do I get the sequence of values in my own custom order, to get for example

;=> (4 2 3 1 5)

what I eventually want to do is serialize the values to a string, doing something like this

(defn serialize [m sep] (apply str (concat (interpose sep (vals m)) ["\n"])))

(this example function was taken from the "serialize an input-map into string" post)

but I need to specify the order of the vals.

Upvotes: 13

Views: 4877

Answers (4)

Justin Kramer
Justin Kramer

Reputation: 4003

Maps are functions of their keys, so you can do this:

(map mymap [:e :a :d :b :f])
=> (4 2 3 1 5)

Upvotes: 26

Rob Buhler
Rob Buhler

Reputation: 2511

I don't want to sort (although thanks for the sorting tips), I just want to specify the order when I pull the values from the map. I found a way to do it - destructuring the map.

(let [{:keys [a b d e f]} mymap]
   (println e a d b f))

Upvotes: 0

Hamza Yerlikaya
Hamza Yerlikaya

Reputation: 49329

For 1.3 you can use the priority-map,

http://clojure.github.com/clojure-contrib/branch-master/priority-map-api.html

or you can use sort-by,

(let [m { 1 8 3 6 5 4 7 2}]
  (println (map first (sort-by second m)))
  (println (map first (sort-by first m))))

(7 5 3 1)
(1 3 5 7)

Upvotes: 4

Nicolas Modrzyk
Nicolas Modrzyk

Reputation: 14197

In case you want to sort the map depending on the keys, and then get the values, Brian has an example on how to do this using sort-by

Or you can just implement your own sort comparator

Upvotes: 0

Related Questions