In Ruby, there is Kernel#Array
method, which acts like this:
Array([1, 2, 3]) #=> [1, 2, 3]
Array(1..5) #=> [1, 2, 3, 4, 5]
Array(9000) #=> [9000]
Array(nil) #=> []
In other words, it converts nil to empty array, non-collections to singleton arrays, and kinds of collection-like objects (i.e. objects which respond to #to_ary
or #to_a
) to arrays.
I want to have something similar to this in Clojure:
(to-seq [1 2 3]) ;=> (1 2 3)
(to-seq (range 1 5)) ;=> (1 2 3 4)
(to-seq 9000) ;=> (9000)
(to-seq nil) ;=> nil; () is ok too
That's what I've got so far:
(defn to-seq [x] (if (seqable? x) (seq x) '(x)))
But I don't like it because:
- The
seqable?
function evaporated during the explosion of monolithic clojure-contrib. I don't want to include huge ancient no-longer-supported library to my project just for one function. - I have a feeling that there must be a built-in function that is either in clojure.core or in clojure.contrib.whatever. Or that there's more idiomatic approach.
The exact output type of to-seq
is not important. The main thing is that I'd like to use its output, say, in list comprehensions:
(for [person (to-seq person-or-people)] ...)
So if will be a vector - it's ok. If it will be a vector, a Java array, a list or nil depending on the input - that's fine too.
==== UPD ====
The almost final version:
(defn to-seq [x] (if (or (nil? x) (coll? x)) x [x]))
The final version:
(defn to-seq ..blabla..)
I don't need to-seq, it doesn't look attractive.
'(x)
evaluates to a singleton list containing the symbolx
; you'll want to use(list x)
or[x]
instead. – Michał Marczyk