2012-07-20 36 views
9

我經常發現自己需要的一種擴展reduce的,每當我必須在每次處理一個項目(如減少)的,積累一些樣的結果(如降低),但這樣做的過程中基於最序列的前一項(與減少不同)。Clojure的:減少三個參數

例如(傻之一),添加1到累加器如果當前項和在前一個都是偶數和減去一個的他們是奇數。這只是一個愚蠢的例子,但我經常遇到這種問題。我通常將矢量作爲累加器,以便第一項是真正的聚合,第二項是前一項。這不是非常優雅,當然冗長。

是否有一個核心功能在這些情況下幫助?處理這種問題的最習慣的方式是什麼?由於

+0

請寫下這樣的例子。 輸入:XXX 輸出:YYY – blueiur 2012-07-20 13:03:35

回答

15

partition救援。

(reduce (fn [i [a b]] 
      (cond 
      (and (even? a) (even? b)) (inc i) 
      (and (odd? a) (odd? b)) (dec i) 
      :else i)) 
     0 (partition 2 1 input)) 

還是有點更簡潔:

(reduce (fn [i pair] 
      (condp every? pair 
      even? (inc i) 
      odd? (dec i) 
      i)) 
     0 (partition 2 1 input)) 
+2

「國家」 是Clojure中只有一個'partition'了。 – ponzao 2012-07-20 18:07:01

10

對於這個特定的問題,我建議kotarak的解決方案,使用分區來跟蹤先前元素。但在一般情況下,你需要在除了你減少的最終「答案」來管理一些狀態,你可以簡單地減小了一對,或地圖或什麼的,並在年底走出累加器值。例如:

(defn parity [coll] 
    (first (reduce (fn [[acc prev] x] 
        [(cond (and (even? prev) (even? x)) (inc acc) 
          (and (odd? prev) (odd? x)) (dec acc) 
          :else acc) 
        x]) 
       [0 (first coll)], (rest coll))))