Clojure中的单级序列展平功能是什么?我现在正在使用apply concat
,但我想知道是否有内置函数,无论是在标准库还是clojure-contrib中。
答案 0 :(得分:19)
我的首要选择是apply concat
。另外,不要忽略(for [subcoll coll, item subcoll] item)
- 根据更广泛的背景,这可能会产生更清晰的代码。
答案 1 :(得分:14)
没有标准功能。在许多情况下,apply concat
是一个很好的解决方案。或者您可以等效地使用mapcat seq
。
apply concat
的问题在于,除了集合/顺序以外的任何内容都处于第一级时,它会失败:
(apply concat [1 [2 3] [4 [5]]])
=> IllegalArgumentException Don't know how to create ISeq from: java.lang.Long...
因此,您可能想要做类似的事情:
(defn flatten-one-level [coll]
(mapcat #(if (sequential? %) % [%]) coll))
(flatten-one-level [1 [2 3] [4 [5]]])
=> (1 2 3 4 [5])
更一般的说法是,缺乏内置函数通常不会阻止您定义自己的函数: - )
答案 2 :(得分:9)
我也使用apply concat
- 我认为核心中没有其他东西。
flatten
是多个级别(通过树步行定义,而不是重复单级扩展)
另请参阅Clojure: Semi-Flattening a nested Sequence,clojure mvc来自http://isti.bitbucket.org/2012/04/01/pipes-clojure-choco-1.html(并且比我预期的要复杂得多)。
更新以澄清懒惰:
flatten-1
你可以看到它对参数进行了32次评估 - 这是为了提高效率,而在其他方面是懒惰的(它不会评估整个列表)。关于分块的讨论,请参阅{{3}}
末尾的评论