Vector 不使用'reduce'或'apply'添加向量的元素`

Vector 不使用'reduce'或'apply'添加向量的元素`,vector,clojure,reduce,Vector,Clojure,Reduce,所以我尝试重新实现reduce方法,这样它就可以添加一些通常可以使用reduce完成的数字,比如: 所以我想,也许可以使用一个递归函数来完成,每次调用向量的第一个元素,然后对向量的其余部分再次添加。大概是这样的: (defn newRd [list] (let [sum 0] (if (not= 0 (count list)) (+ sum (first list)) (newRd (rest list)) ) ) ) 我认为我没有正

所以我尝试重新实现reduce方法,这样它就可以添加一些通常可以使用reduce完成的数字,比如:

所以我想,也许可以使用一个递归函数来完成,每次调用向量的第一个元素,然后对向量的其余部分再次添加。大概是这样的:

(defn newRd [list]
  (let [sum 0]
    (if (not= 0 (count list))
      (+ sum (first list))
      (newRd (rest list))
      )
    )
  )

我认为我没有正确地进行本地存储。有什么建议或更好的方法吗?

代码中有两个错误:

1不将当前总和添加到递归调用结果

2当列表为空时,应返回零

修正的变体:

(defn newRd [list]
  (let [sum 0]
    (if (not= 0 (count list))
      (+ sum (first list)
         (newRd (rest list)))
      sum)))
答复:

user> (newRd [1 2 3 4])
10
user> (sum-list (repeat 1000000 1))
1000000
接下来,您可以稍微更新它:

首先,您实际上不需要let语句中的sum,因为sum总是=0

第二,有一个lib函数是空的吗?检查列表是否为空

(defn newRd [list]
  (if-not (empty? list)
    (+ (first list)
       (newRd (rest list)))
    0))
但请记住:clojure不会进行尾部调用优化,因此很容易导致堆栈owerflow出现长列表:

user> (newRd (repeat 1000000 1))
StackOverflowError   user/newRd (form-init289434844644272272.clj:73)
因此,最好使用循环/重现

(defn sum-list [list]
  (loop [list list sum 0]
    (if (empty? list)
      sum
      (recur (rest list) (+ sum (first list))))))
答复:

user> (newRd [1 2 3 4])
10
user> (sum-list (repeat 1000000 1))
1000000
另一个选项是使函数本身尾部递归:

(defn newRd [list sum]
  (if-not (empty? list)
    (recur (rest list) (+ sum (first list)))
    sum))

user> (newRd (repeat 1000000 1) 0)
1000000
然后,您可以添加额外的arity,以便在每次调用中不传递第二个参数:

(defn newRd
  ([list] (newRd list 0))
  ([list sum]
   (if-not (empty? list)
     (recur (rest list) (+ sum (first list)))
     sum)))
进一步到

您最好实现新的reduce camel,因为这种情况通常不惯用:

(defn new-reduce
  ([f init coll]
   (if (seq coll)
     (recur f (f init (f init (first coll))) (rest coll))
     init))
  ([f coll]
   (if (seq coll)
     (reduce f (first coll) (rest coll))
     (f))))
然后

如果去掉分块,这或多或少就是reduce的源代码直到最近的样子


您使用的两个参数版本依赖于三个参数版本,您可以直接重复使用三个参数版本,而无需显式循环。这意味着每次都要通过f,但它过去就是这样做的。大概携带一个额外的参数比在局部范围内工作要快

如果不是空的?列表就好像是序列表一样好。别以为这样更好。既然空了?只是不是seq coll,我想它是故意添加到库中的:如果不是空列表,它的可读性会更好。在我看来,空列表看起来很自然,如果seq listI同情它,它的可读性会更好,但是docstring是空的吗?说请使用成语seq x而不是not empty?十,。