In Clojure, do you find yourself reaching for a loop recur but you know you should be using reduce? Here's a really simple way to break out of that habit.
Let's start with and example. Starting with a2d
which is the result of invoking (to-array-2d [[11 2 4] [4 5 6] [10 8 -12]])
and len
is the size of the matrix. Which is 3.
This function, written with a loop/recur, calculates the "diagonal sum" of the values of a square matrix of some size.
(defn accu [a2d len]
(reduce +
(loop [vals []
i (- len 1)]
(if (> len (count vals))
(recur (conj vals (aget a2d i i)) (dec i))
vals))))
So invoking this function:
(accu (to-array-2d [[11 2 4] [4 5 6] [10 8 -12]]) 3)
=> 4
Returns 4
because 11 + 5 + -12 = 4
So what does the reduce
version look like?
(defn accu [a2d len]
(reduce +
(reduce #(conj %1 (aget a2d %2 %2)) [] (reverse (range len)))))
Notice how the relevant code is almost exactly the same. Both use (conj vals (aget a2d i i)) (dec i)
to solve the problem. The loop/recur version has much more housekeeping and is not as fast as the reduce version.
Top comments (0)