What's the one-level sequence flattening function in Clojure?

My general first choice is apply concat. Also, don't overlook (for [subcoll coll, item subcoll] item) -- depending on the broader context, this may result in clearer code.


There's no standard function. apply concat is a good solution in many cases. Or you can equivalently use mapcat seq.

The problem with apply concat is that it fails when there is anything other than a collection/sequential is at the first level:

(apply concat [1 [2 3] [4 [5]]])
=> IllegalArgumentException Don't know how to create ISeq from: java.lang.Long...

Hence you may want to do something like:

(defn flatten-one-level [coll]  
  (mapcat  #(if (sequential? %) % [%]) coll))

(flatten-one-level [1 [2 3] [4 [5]]])
=> (1 2 3 4 [5])

As a more general point, the lack of a built-in function should not usually stop you from defining your own :-)


i use apply concat too - i don't think there's anything else in the core.

flatten is multiple levels (and is defined via a tree-walk, not in terms of repeated single level expansion)

see also Clojure: Semi-Flattening a nested Sequence which has a flatten-1 from clojure mvc (and which is much more complex than i expected).

update to clarify laziness:

user=> (take 3 (apply concat (for [i (range 1e6)] (do (print i) [i]))))
012345678910111213141516171819202122232425262728293031(0 1 2)

you can see that it evaluates the argument 32 times - this is chunking for efficiency, and is otherwise lazy (it doesn't evaluate the whole list). for a discussion of chunking see comments at end of http://isti.bitbucket.org/2012/04/01/pipes-clojure-choco-1.html