我正在学习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)
任何人都可以帮我看看我的功能有什么问题吗?我已经在网上搜索了这个错误,但我找不到有用的解决方案。
答案 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)))