40

Clojureの1レベルのシーケンスフラット化機能とは何ですか?私はapply concat今のところ使用していますが、標準ライブラリまたはclojure-contribのいずれかに、そのための組み込み関数があるのではないかと思います。

4

3 に答える 3

24

私の一般的な最初の選択肢はapply concatです。また、見落とさないでください(for [subcoll coll, item subcoll] item)。より広いコンテキストによっては、コードがより明確になる可能性があります。

于 2012-05-24T09:46:50.953 に答える
21

標準機能はありません。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])

より一般的なポイントとして、組み込み関数がなくても、通常、独自の関数を定義することを妨げることはありません:-)

于 2012-05-24T02:54:13.897 に答える
10

私も使っapply concatています-コアには他に何もないと思います。

flatten複数のレベルです(単一レベルの拡張の繰り返しではなく、ツリーウォークを介して定義されます)

Clojure:flatten-1 from clojure mvcを持つ(そして私が予想していたよりもはるかに複雑な)ネストされたシーケンスのセミフラット化も参照してください。

怠惰を明確にするための更新:

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

引数を32回評価していることがわかります。これは効率を上げるためのチャンクであり、それ以外の場合は怠惰です(リスト全体を評価しません)。チャンキングの説明については、 http://isti.bitbucket.org/2012/04/01/pipes-clojure-choco-1.htmlの最後にあるコメントを参照してください。

于 2012-05-23T15:48:00.973 に答える