我正在遍历列表,逐步建立状态,偶尔遇到某个哨兵时,我会返回结果。如果我是在Python中执行此操作,则我会懒惰地返回yield
结果,并在执行时跟踪函数本地范围内的状态:
# this is simplified for illustration
def yielder(input_list):
state = 0
for item in input_list:
if item = 'SENTINEL':
yield state * 2
state = 0
else:
state += item
yielder([1, 5, 2, 5, 'SENTINEL', 4, 6, 7]) # [26, 34]
Run Code Online (Sandbox Code Playgroud)
我的第一个实现使用reduce
,但这并不如yield
:
iterate
可以用来减轻后者,但我实际上并不希望为每个输入项都返回一些东西,因此需要更多的调整。
Clojure中的惯用方式是什么?
使用懒惰-SEQ你提到你可以建立这个自己或者你可以使用partition
和reduce
分割问题转化阶段,然后拧在一起。我将使用thread-last宏单独显示每个步骤:
user> (->> [1, 5, 2, 5, :SENTINEL, 4, 6, 7] ;; start with data
(partition-by #(= :SENTINEL %)) ;; ((1 5 2 5) (:SENTINEL) (4 6 7))
(take-nth 2) ;; ((1 5 2 5) (4 6 7))
(map #(* 2 (reduce + %)))) ;; the map here keeps it lazy
(26 34)
Run Code Online (Sandbox Code Playgroud)
这是直接在lazy-seq中使用:
user> (defn x [items]
(when (seq items)
(lazy-seq (cons (* 2 (reduce + (take-while #(not= :SENTINEL %) items)))
(x (rest (drop-while #(not= :SENTINEL %) items)))))))
#'user/x
user> (x [1, 5, 2, 5, :SENTINEL, 4, 6, 7])
(26 34)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1634 次 |
最近记录: |