2012-07-20 4 views
9

私はしばしば(reduceのように)アイテムを処理しなければならないときに、ある種の結果(reduceのようなもの)を蓄積しなければならないときに、シーケンスの前の項目(reduceとは異なります)。Clojure:3つのパラメータを使って減らす

たとえば、現在のアイテムと前のアイテムの両方が偶数であり、1つが奇数である場合、アキュムレータに1を加算します。これは単なる愚かなケースですが、私はこの種の問題に頻繁に遭遇しました。私は一般的にベクトルをアキュムレータとして作って、最初のアイテムは実際の集約であり、2番目のアイテムは前のアイテムです。これは非常に優雅ではないと確かに冗長です。

このような場合に役立つ中心的な機能はありますか?このような問題に対処する最も慣れ親しんだ方法は何ですか?ありがとう

+0

このような例を書いてください。 入力:xxx 出力:yyy – blueiur

答えて

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でただ1つの 'パーティション 'です。 – ponzao

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)))) 
関連する問題