I am often finding myself using a lazy list when I want a vector, and vice versa. Also, sometimes I have a vector of maps, when I really wanted a set of maps. Are there any helper functions to help me to convert between these types?
6 Answers
Let's not forget that trusty old into
lets you take anything seq
able (list, vector, map, set, sorted-map) and an empty container you want filled, and puts it into
it.
(into [] '(1 2 3 4)) ==> [1 2 3 4] "have a lazy list and want a vector"
(into #{} [1 2 3 4]) ==> #{1 2 3 4} "have a vector and want a set"
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2} "have a set of vectors want a map"
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps"
into
is a wrapper around conj
, which is the base abstraction for inserting new entries appropriately into a collection based on the type of the collection. The principle that makes this flow so nicely is that Clojure is build on composable abstractions, in this case into
on top of conj
on top of collection and seq
.
The above examples would still compose well if the recipient was being passed in at run time: because the underlying abstractions (seq
and conj
) are implemented for all the collections (and many of Java's collections also), so the higher abstractions don't need to worry about lots of special data-related corner cases.

- 13,293
- 2
- 29
- 37

- 90,827
- 27
- 201
- 284
-
3+1 for into... worth noting that it also works with non-empty original containers as well (i.e. when you want to add to a collection) – mikera Feb 24 '11 at 14:05
-
12It's also worth noting that because `into` uses `conj`, doing `(into '() some-seq)` will yield a list that's the *reverse* of some-seq, because `conj` conses onto lists. – Chuck Dec 17 '13 at 19:15
-
It's worth noting that `into` utilizes transients (for most seq types) for better performance characteristics than most other conversion means. – Jarred Humphrey Apr 25 '16 at 23:45
-
And it now works with transducers, which didn't exist at the time this answer was written (I don't know if transients did either) (This answer is old enough to enrol in kindergarten) – Arthur Ulfeldt Apr 26 '16 at 00:11
vec
, set
and generally into
are your friends to easily "convert" to another collection type.
How do you want to transform a vector of maps into a map of maps? You need a key, can you provide use with sample input/expected output?

- 7,939
- 28
- 32
For vectors there is the vec
function
user=> (vec '(1 2 3))
[1 2 3]
For lazy sequences there is the lazy-seq
function
user=> (lazy-seq [1 2 3])
(1 2 3)
For converting into sets, there is the set
function
user=> (set [{:a :b, :c :d} {:a :b} {:a :b}])
#{{:a :b} {:a :b, :c :d}}

- 69,903
- 20
- 143
- 156
-
4When you have something non-lazy calling `lazy-seq` instead of `seq` just adds a useless indirection. If really you want to return something non-nil even fore empty collectiosn thene there's `sequence`. `lazy-seq` is somewhat of a low-level construct. – cgrand Feb 23 '11 at 12:35
To convert a vector to a list you can also use for
, like this:
=> (for [i [1 2 3 4]] i)
(1 2 3 4)
When you don't want to manipulate the data, just use seq
on the vector:
=> (seq [1 2 3])
(1 2 3)

- 140
- 2
- 5
There is no need to convert a vector to a list. Clojure will treat a vector as it would treat a list - as a sequence - when a sequence is required. For example,
user=> (cons 0 [1 2 3])
(0 1 2 3)
If you need to make sure that the vector is being treated as a sequence, wrap it in seq
:
user=> (conj [1 2 3] 0) ; treated as a vector
[1 2 3 0]
user=> (conj (seq [1 2 3]) 0) ; treated as a sequence
(0 1 2 3)
If you have a vector of maps, and you want a set of maps, it doesn't matter that the vector holds maps. You just convert the vector to a set as usual:
user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}])
#{{:a 1, :b 2} {"four" 4, "three" 3}}

- 13,293
- 2
- 29
- 37