2016-12-01 43 views
0

有沒有一種更優雅的方式讓into可以處理單個項目和列表,而不是以下(無可否認的殘酷)功能?將單身和名單放入clojure列表中

(defn into-1-or-more 
    [this-list list-or-single] 
    (into this-list (flatten (conj [] list-or-single)))) 

,它可以處理兩種:

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

或者:

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

我建立一個收集與降低使用into []在列表從函數的結果。但是,某些功能會返回單個項目,而其他功能會返回項目列表。像:

(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-heisenparameter – 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])。