如何使用减少并进入正确

时间:2017-07-18 01:40:23

标签: clojure

我正在学习Clojure,实际上我正在练习练习,但我遇到了问题:

我需要创建一个sum-consecutives函数,它对数组中的连续元素求和,产生一个新元素,例如:

[1,4,4,4,0,4,3,3,1]  ; should return [1,12,0,4,6,1]

我做了这个功能应该可以正常工作:

(defn sum-consecutives [a]
  (reduce #(into %1 (apply + %2)) [] (partition-by identity a)))

但它引发了一个错误:

  

IllegalArgumentException不知道如何从以下位置创建ISeq:   java.lang.Long clojure.lang.RT.seqFrom(RT.java:542)

任何人都可以帮我看看我的功能有什么问题吗?我已经在网上搜索了这个错误,但我找不到有用的解决方案。

2 个答案:

答案 0 :(得分:2)

您可能希望使用conj代替into,因为into期望其第二个参数为seq

(defn sum-consecutives [a]
  (reduce 
    #(conj %1 (apply + %2))
    [] 
    (partition-by identity a)))

(sum-consecutives [1,4,4,4,0,4,3,3,1]) ;; [1 12 0 4 6 1]

或者,如果确实想要使用into,您可以将调用包含在apply +中,如下所示:

(defn sum-consecutives [a]
  (reduce 
    #(into %1 [(apply + %2)])
    [] 
    (partition-by identity a)))

答案 1 :(得分:2)

partition-by开始,您的方法是合理的。但是,让我们 通过步骤来总结它产生的每个子序列。

(let [xs [1 4 4 4 0 4 3 3 1]]
  (partition-by identity xs))  ;=> ((1) (4 4 4) (0) (4) (3 3) (1))

要获得总和,您可以使用reduce(虽然简单apply 而是would also work 这里); e.g:

(reduce + [4 4 4])  ;=> 12

现在将所有内容放在reduce来自map的{​​{1}}上面的每个子序列:

(let [xs [1 4 4 4 0 4 3 3 1]]
  (map #(reduce + %) (partition-by identity xs)))  ;=> (1 12 0 4 6 1)

一些注释......

我正在使用xs来表示你的向量(正如我所建议的那样) Clojure Style Guide)。

let有时是一种方便的实验形式 数据构建到最终功能。

除了偶尔之外,不需要逗号并且通常会分散注意力 使用哈希映射。

所以基于这一切的最终功能看起来像是:

(defn sum-consecutives [coll]
  (map #(reduce + %) (partition-by identity coll)))