Clojure: 带有三个参数的reduce函数

14

每当我需要逐个处理项目(就像reduce),累积某种结果(就像reduce),但是根据先前项处理序列(不同于reduce)时,经常需要一种扩展的reduce

例如(一个愚蠢的例子),如果当前项目和上一个项目都是偶数,则将1添加到累加器中,如果它们是奇数,则减去1。这只是一个愚蠢的情况,但我经常遇到这种问题。我通常使用一个向量作为累加器,以便第一个项目是真正的聚合,第二个项目是先前的项目。这不是非常优雅,而且显然冗长。

是否有核心函数可以帮助处理这些情况?最惯用的处理方法是什么?谢谢


输入:xxx 输出:yyy - blueiur
2个回答

18

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中,“状态”只需要一个“分区”就可以实现。 - ponzao

10

对于这个特定问题,我推荐使用kotarak的解决方案,使用partition来跟踪先前的元素。但在一般情况下,当您需要管理一些状态以及reduce最终的“答案”时,您可以简单地对一对、映射或其他内容进行reduce,并在结束时获取累加器值。例如:

(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))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接