Alan Thompson
Alan Thompson

Reputation: 29984

How can I convert a map into a vector?

If I have a map that looks like:

{:a 1 :b 2 :c 3}

how can I convert it into a vector like:

[:a 1 :b 2 :c 3]

Upvotes: 1

Views: 1939

Answers (5)

Rulle
Rulle

Reputation: 4901

Combining into with a catting transducer is quite concise:

(into [] cat {:a 1 :b 2 :c 3})
;;=> [:a 1 :b 2 :c 3]

Upvotes: 12

Gwang-Jin Kim
Gwang-Jin Kim

Reputation: 10010

Use mapcat and vec to achieve it:

(vec (mapcat identity {:a 1 :b 2 :c 3}))
;; => [:a 1 :b 2 :c 3]

Upvotes: 3

Jason
Jason

Reputation: 12333

I suggest using flatten and vec

(vec (flatten (vec {:a 1 :b 2 :c 3})))

On the repl it will look like this:

user=> (vec (flatten (vec {:a 1 :b 2 :c 3})))
[:a 1 :b 2 :c 3]

Upvotes: -1

Lee
Lee

Reputation: 144206

You can use reduce-kv:

(defn kv-vec [m] (reduce-kv conj [] m))

Upvotes: 5

Alan Thompson
Alan Thompson

Reputation: 29984

Here is a simple function for this purpose

(ns demo.core
  (:require 
    [schema.core :as s]
    [tupelo.schema :as tsk]))

(s/defn keyvals :- [s/Any]
  "For any map m, returns the (alternating) keys & values of m as a vector, suitable for reconstructing m via
   (apply hash-map (keyvals m)). (keyvals {:a 1 :b 2} => [:a 1 :b 2] "
  [m :- tsk/Map]
  (reduce into [] (seq m)))

with unit test:

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(dotest
  (let [m1 {:a 1 :b 2 :c 3}
        m2 {:a 1 :b 2 :c [3 4]}]
    (is= [:a 1 :b 2 :c 3]   (t/keyvals m1))
    (is= m1 (apply hash-map (t/keyvals m1)))
    (is= m2 (apply hash-map (t/keyvals m2)))))

As the unit test shows, keyvals is the inverse of (apply hashmap ...) and can be used for deconstructing a map. It can be useful when calling functions that require keyword args.

Upvotes: 0

Related Questions