2016-12-01 7 views
0

intoは、以下の(間違いなく残虐な)機能よりも単一項目とリストを扱うよりエレガントな方法がありますか?シングルスとリストをクローズのリストに入れよう

扱うどちらかができ
(defn into-1-or-more 
    [this-list list-or-single] 
    (into this-list (flatten (conj [] list-or-single)))) 

:私は、リスト内の関数の結果とinto []を使用して削減してコレクションを構築してい

(into-1-or-more [1 2 3 4] [5 6 7 8]) 
;[1 2 3 4 5 6 7 8] 

(into-1-or-more [1 2 3 4] 5) 
;[1 2 3 4 5] 

かを。しかし、関数の中には単一のアイテムを返すものもあれば、アイテムのリストを返すものもあります。 Like:

(reduce #(into [] (% data)) [func-return-item func-return-list func-return-either]) 

最高の解決策は、代わりに次のようにすることですか?

(into [] (flatten (map #(% data) [func-return-item ...]) 
+0

'reduce'は必要ない場合には使用しないでください。' reduce'は遅延しません。代わりに 'map'があります。 – Marcs

+0

この特定のケースでは、すべてのデータがとにかく消費されます。もちろんあなたはもちろんです。 –

+1

https://stuartsierra.com/2015/06/10/clojure-donts-heisenパラメーター – OlegTheCat

答えて

3

それはあなたが取得しているか戻り値の型を確実に知ることが、より理想的であるが、ここでは単純な答えです:

(flatten [ curr-list (mystery-fn) ]) 

例:

(flatten [[1 2 3] 9 ]) 
;=> (1 2 3 9) 
(flatten [[[1] 2 3] [4 5] 6 ]) 
;=> (1 2 3 4 5 6) 

は、あなたはそれをラップすることができ必要に応じて関数に変換しますが、必要性はほとんどありません。

2

このトランスデューサはシーケンシャル入力を平坦化が、唯一つの「レベル」によって:

(defn maybe-cat [rf] 
    (let [catrf (cat rf)] 
    (fn 
     ([] (rf)) 
     ([result] (rf result)) 
     ([result input] 
     (if (sequential? input) 
     (catrf result input) 
     (rf result input)))))) 

例:この例が示すように

(into [] maybe-cat [[:foo] :bar [[:quux]]]) 
;= [:foo :bar [:quux]] 

、このアプローチはシーケンシャルコレクションを含めることを可能にします追加のシーケンシャルレイヤーにラップすることによって([[:quux]]は出力に[:quux]を生成します)。

関連する問題