在 Ruby 中,有一个Kernel#Array
方法,它的作用如下:
Array([1, 2, 3]) #=> [1, 2, 3]
Array(1..5) #=> [1, 2, 3, 4, 5]
Array(9000) #=> [9000]
Array(nil) #=> []
换句话说,它将 nil 转换为空数组,将非集合转换为单例数组,并将各种类似集合的对象(即响应#to_ary
or的对象#to_a
)转换为数组。
我想在 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
这就是我到目前为止所得到的:
(defn to-seq [x] (if (seqable? x) (seq x) '(x)))
但我不喜欢它,因为:
- 在整体 clojure-contrib爆炸期间,该
seqable?
功能消失了。我不想仅仅为了一个功能在我的项目中包含庞大的、不再受支持的库。 - 我觉得clojure.core或clojure.contrib.whatever中必须有一个内置函数。或者有更惯用的方法。
的确切输出类型to-seq
并不重要。主要是我想在列表推导中使用它的输出:
(for [person (to-seq person-or-people)] ...)
所以如果将是一个向量 - 没关系。如果它是一个向量、一个 Java 数组、一个列表或 nil,取决于输入 - 这也很好。
==== 更新 ====
几乎是最终版本:
(defn to-seq [x] (if (or (nil? x) (coll? x)) x [x]))
最终版本:
(defn to-seq ..blabla..)
我不需要排序,它看起来不吸引人。