我有一个seq (2 3 1 4).
我想迭代它,并且当下一个元素更小时,prev元素将替换两个元素另一个seq.'( - 4 1).
所以f('(2 3 1 4))=>(2( - 3 1)4).我怎么写呢?
基本上 -
1)我想同时访问seq中的两个相邻元素.2)编辑并返回该点的新seq.3)继续处理新返回的seq.
一般来说,实现上述3的机制是什么.(map,reduce都让我一次只能访问一个elem.)
这实际上不是成对消费的问题,因为您对序列进行分区的方式取决于您对当前对的处理方式.请注意,有时您会从sequence()中使用一个项目2 3,但有时您会使用两个项目(3 1).
正因为如此,你不能使用任何的创造Clojure中的滑动窗口(通常的方法(partition 2 1 coll),(map fn coll (rest coll))等等).您需要使用明确递归的内容.
你的算法应该是这样的:
(- first second); 递归剩余物品这是该算法的惰性实现.你也可以使用recur和累加器这样做- 它不会是懒惰但它仍然可以工作.
(defn combine-if-gt-next
[[f s & r]]
(cond
(nil? f) nil
(nil? s) (cons f nil)
(> f s) (cons (list '- f s) (lazy-seq (combine-if-gt-next r)))
true (cons f (lazy-seq (combine-if-gt-next (cons s r))))))
Run Code Online (Sandbox Code Playgroud)
例子:
(combine-if-gt-next '(2 3 1 4)) ; your example
;; (2 (- 3 1) 4)
(combine-if-gt-next [])
;; nil
(combine-if-gt-next [1 2 3])
;; (1 2 3)
(combine-if-gt-next [2 3 4 1])
;; (2 3 (- 4 1))
(combine-if-gt-next [2 3 4 1 4])
;; (2 3 (- 4 1) 4)
(combine-if-gt-next [2 1 4 1 4 5 1])
;; ((- 2 1) (- 4 1) 4 (- 5 1))
(combine-if-gt-next [5 4 3 2 1])
;; ((- 5 4) (- 3 2) 1)
Run Code Online (Sandbox Code Playgroud)