Calculating the Moving Average of a List

后端 未结 18 1183
悲哀的现实
悲哀的现实 2020-12-07 09:01

This weekend I decided to try my hand at some Scala and Clojure. I\'m proficient with object oriented programming, and so Scala was easy to pick up as a language, but wante

18条回答
  •  醉话见心
    2020-12-07 09:38

    Here is Clojure pretending to be a more functional language. This is fully tail-recursive, btw, and includes leading zeroes.

    (defn moving-average [period values]
      (loop [[x & xs]  values
             window    []
             ys        []]
    
        (if (and (nil? x) (nil? xs))
          ;; base case
          ys
    
          ;; inductive case
          (if (< (count window) (dec period))
            (recur xs (conj window x) (conj ys 0.0))
            (recur xs
                   (conj (vec (rest window)) x)
                   (conj ys (/ (reduce + x window) period)))))))
    
    (deftest test-moving-average
      (is (= [0.0 0.0 0.0 4.75 5.0 6.0 7.25 8.0 8.25 6.5]
             (moving-average 4 [2.0 4.0 7.0 6.0 3.0 8.0 12.0 9.0 4.0 1.0]))))
    

    Usually I put the collection or list parameter last to make the function easier to curry. But in Clojure...

    (partial moving-average 4)
    

    ... is so cumbersome, I usually end up doing this ...

    #(moving-average 4 %)
    

    ... in which case, it doesn't really matter what order the parameters go.

提交回复
热议问题